I've noticed that setting `LookupList` and `LookupWebId` not always work. Therefor, I have a function that replace XML attributes in field schema. Take a look at the following code: public static string ReplaceXmlAttributeValue(string xml, string attributeName, string value) { if (string.IsNullOrEmpty(xml)) { throw new ArgumentNullException("xml"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } int indexOfAttributeName = xml.IndexOf(attributeName, StringComparison.CurrentCultureIgnoreCase); if (indexOfAttributeName == -1) { xml = xml.Replace("<Field", "<Field " + attributeName + "='" + value + "'"); return xml; } int indexOfAttibuteValueBegin = xml.IndexOf('"', indexOfAttributeName); int indexOfAttributeValueEnd = xml.IndexOf('"', indexOfAttibuteValueBegin + 1); return xml.Substring(0, indexOfAttibuteValueBegin + 1) + value + xml.Substring(indexOfAttributeValueEnd); } I use it like this: Get both lists and the lookup field that you want to set up: var mainList = web.GetList(SPUtility.ConcatUrls(web.ServerRelativeUrl, "Lists/MainList")); var mainListLookupField = (SPFieldLookup)mainList.Fields.GetFieldByInternalName("LookupField"); var lookupList = web.GetList(SPUtility.ConcatUrls(web.ServerRelativeUrl, "Lists/LookupList")); Replace `List` and `WebId` attributes in your Lookup Field's schema: mainListLookupField.SchemaXml = ReplaceXmlAttributeValue(ReplaceXmlAttributeValue(mainListLookupField.SchemaXml, "List", lookupList.ID.ToString()), "WebId", web.ID.ToString()); mainListLookupField.LookupField = "Title"; mainListLookupField.Update(); Hope this helps!