{"record":{"id":"07844d2ad5f5e81b","repo":"dgraph-io/dgraph","slug":"while-json-unmarshaling-result-from-remote-introsp","errorCode":null,"errorMessage":"while json unmarshaling result from remote introspection query","messagePattern":"while json unmarshaling result from remote introspection query","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/schema/remote.go","lineNumber":76,"sourceCode":"\tfor k := range headers {\n\t\treq.Header.Set(k, headers.Get(k))\n\t}\n\tclient := &http.Client{Timeout: 5 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\tif err := resp.Body.Close(); err != nil {\n\t\t\tglog.Warningf(\"error closing body: %v\", err)\n\t\t}\n\t}()\n\tbody, err = io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresult := &introspectedSchema{}\n\treturn result, errors.Wrapf(json.Unmarshal(body, result),\n\t\t\"while json unmarshaling result from remote introspection query\")\n}\n\nconst (\n\tlist        = \"LIST\"\n\tnonNull     = \"NON_NULL\"\n\tinputObject = string(ast.InputObject)\n)\n\nconst introspectionQuery = `\n\tquery {\n\t  __schema {\n\t\tqueryType { name }\n\t\tmutationType { name }\n\t\tsubscriptionType { name }\n\t\ttypes {\n\t\t  ...FullType\n\t\t}","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/schema/remote.go#L58-L94","documentation":"After Dgraph executes the introspection query against the remote GraphQL schema, it reads the body and unmarshals it into introspectedSchema. If the body is not valid JSON in the expected introspection envelope, json.Unmarshal fails and this wrapped error is returned. Usually the remote returned an error page, empty body, or a non-standard introspection response.","triggerScenarios":"validateRemoteGraphql calls introspectRemoteSchema, the remote responds (possibly HTTP 200) but the body isn't the expected JSON introspection result — truncated response, HTML error page, or a schema format the introspectedSchema struct doesn't match.","commonSituations":"Remote endpoint doesn't support the introspection query version Dgraph sends; gateway/CDN intercepting the response; remote requires auth so it returns an HTML/JSON auth error instead of introspection data.","solutions":["Test the introspection POST against the remote URL manually (curl) and inspect the raw body","Ensure the remote is a real GraphQL endpoint supporting introspection","Check auth headers in the @custom directive config","Confirm no proxy/CDN is rewriting or blocking the response"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const res = await fetch(url, introspectionPost)\ntry { JSON.parse(await res.text()) } catch { throw new Error('remote introspection response is not valid JSON') }","typeGuard":null,"tryCatchPattern":"err := schema.ValidateCustom(dgSchema, gqlSchema)\nif err != nil && strings.Contains(err.Error(), \"while json unmarshaling result\") {\n  // manually curl the remote endpoint and inspect the raw body\n}","preventionTips":["Curl the remote with the introspection query before wiring @custom","Confirm content-type is application/json","Check auth headers so the remote doesn't return an error page","Ensure no proxy rewrites the response body"],"tags":["graphql","remote-schema","json","introspection","dgraph"],"backgroundTag":"introspection-parse-failed","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}