{"record":{"id":"56427390d538354d","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-parse-nodes-w","errorCode":null,"errorMessage":"cannot parse nodes: %w","messagePattern":"cannot parse nodes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promscrape/discovery/dockerswarm/nodes.go","lineNumber":76,"sourceCode":"\treturn addNodeLabels(nodes, cfg.port), nil\n}\n\nfunc getNodes(cfg *apiConfig) ([]node, error) {\n\tfiltersQueryArg := \"\"\n\tif cfg.role == \"nodes\" {\n\t\tfiltersQueryArg = cfg.filtersQueryArg\n\t}\n\tresp, err := cfg.getAPIResponse(\"/nodes\", filtersQueryArg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot query dockerswarm api for nodes: %w\", err)\n\t}\n\treturn parseNodes(resp)\n}\n\nfunc parseNodes(data []byte) ([]node, error) {\n\tvar nodes []node\n\tif err := json.Unmarshal(data, &nodes); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot parse nodes: %w\", err)\n\t}\n\treturn nodes, nil\n}\n\nfunc addNodeLabels(nodes []node, port int) []*promutil.Labels {\n\tvar ms []*promutil.Labels\n\tfor _, node := range nodes {\n\t\tm := promutil.NewLabels(16)\n\t\tm.Add(\"__address__\", discoveryutil.JoinHostPort(node.Status.Addr, port))\n\t\tm.Add(\"__meta_dockerswarm_node_address\", node.Status.Addr)\n\t\tm.Add(\"__meta_dockerswarm_node_availability\", node.Spec.Availability)\n\t\tm.Add(\"__meta_dockerswarm_node_engine_version\", node.Description.Engine.EngineVersion)\n\t\tm.Add(\"__meta_dockerswarm_node_hostname\", node.Description.Hostname)\n\t\tm.Add(\"__meta_dockerswarm_node_id\", node.ID)\n\t\tm.Add(\"__meta_dockerswarm_node_manager_address\", node.ManagerStatus.Addr)\n\t\tm.Add(\"__meta_dockerswarm_node_manager_leader\", fmt.Sprintf(\"%t\", node.ManagerStatus.Leader))\n\t\tm.Add(\"__meta_dockerswarm_node_manager_reachability\", node.ManagerStatus.Reachability)\n\t\tm.Add(\"__meta_dockerswarm_node_platform_architecture\", node.Description.Platform.Architecture)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promscrape/discovery/dockerswarm/nodes.go#L58-L94","documentation":"parseNodes json.Unmarshals the /nodes response body into []node and wraps unmarshal failures with this error. The HTTP layer succeeded but the payload is not the expected JSON array of Swarm nodes. Typically a proxy-injected body or a schema/type mismatch between the daemon's output and the library's struct.","triggerScenarios":"json.Unmarshal(data, &nodes) errors: body is an HTML error page, empty, or a JSON object instead of an array; a field type changed in a newer Docker engine version.","commonSituations":"MitM proxy or SSO gateway returning HTML; Docker Engine upgrade changing node JSON types; daemon returning an error object {\"message\":...} with a 200 that then fails unmarshal into an array.","solutions":["Inspect the raw /nodes response body with the same credentials","Ensure the response is a JSON array of node objects","Test with an equivalent Docker API version to rule out schema drift","Bypass intermediate proxies to rule out body substitution"],"exampleFix":"null","handlingStrategy":"type-guard","validationCode":"// Go: reject non-array payloads before decoding into []node\nif len(data) == 0 || data[0] != '[' {\n    return fmt.Errorf(\"/nodes returned non-array payload: %.200s\", data)\n}","typeGuard":"// Go: narrow via a lightweight probe decode\nfunc isNodeArray(data []byte) bool {\n    var probe []json.RawMessage\n    return json.Unmarshal(data, &probe) == nil\n}","tryCatchPattern":"null","preventionTips":["Compare raw daemon output after every Docker Engine upgrade","Disable body-rewriting middleboxes on the API path","Assert application/json content type in a preflight check"],"tags":["docker-swarm","docker-api","json","parsing"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}