{"record":{"id":"6bbd3b4afab8b6ab","repo":"ipfs/kubo","slug":"failed-to-decode-file-as-config","errorCode":null,"errorMessage":"failed to decode file as config","messagePattern":"failed to decode file as config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/config.go","lineNumber":651,"sourceCode":"\tif !ok {\n\t\treturn \"\", errors.New(\"private key in config was not a string\")\n\t}\n\tident := config.Identity{PrivKey: pkstr}\n\tpk, err := ident.DecodePrivateKey(\"\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to decode PrivKey: %w\", err)\n\t}\n\tid, err := peer.IDFromPrivateKey(pk)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to derive PeerID from PrivKey: %w\", err)\n\t}\n\treturn id, nil\n}\n\nfunc replaceConfig(r repo.Repo, file io.Reader) error {\n\tvar newCfg config.Config\n\tif err := json.NewDecoder(file).Decode(&newCfg); err != nil {\n\t\treturn errors.New(\"failed to decode file as config\")\n\t}\n\n\t// Handle Identity.PrivKey (secret)\n\n\tif len(newCfg.Identity.PrivKey) != 0 {\n\t\treturn errors.New(\"setting private key with API is not supported\")\n\t}\n\n\tkeyF, err := getConfig(r, config.PrivKeySelector)\n\tif err != nil {\n\t\treturn errors.New(\"failed to get PrivKey\")\n\t}\n\n\tpkstr, ok := keyF.Value.(string)\n\tif !ok {\n\t\treturn errors.New(\"private key in config was not a string\")\n\t}\n","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/config.go#L633-L669","documentation":"`ipfs config replace` decodes the input file into a config.Config struct. This error is returned when the file is not valid JSON or its structure does not match the config schema, discarding the detailed decode error. Note it does NOT use %w, so the underlying JSON error is not shown.","triggerScenarios":"Running `ipfs config replace <file>` where the file contains invalid JSON, YAML/TOML instead of JSON, a partial config with wrong field types, or empty/HTML content (e.g. a downloaded error page).","commonSituations":"Redirecting `ipfs config show` output through tools that alter it; downloading a config from a URL that returned an HTML error page; replacing with a partial config fragment instead of a full config.","solutions":["Validate the file first: `jq empty new-config.json` — fix any JSON syntax errors it reports","Ensure it's a full config in kubo's JSON schema: generate a reference with `ipfs config show > ref.json` and diff structure","Check the file isn't HTML/empty: `head -c 200 new-config.json` — re-download or re-export if so","Remember replace also refuses to set Identity.PrivKey via the API; keep the file's Identity handling in mind (see the 'setting private key with API is not supported' error)"],"exampleFix":"// before\nipfs config replace config.yaml   # YAML not accepted\n// after\nipfs config show > backup.json\njq '. + {\"Addresses\": ...}' backup.json > new.json && jq empty new.json\nipfs config replace new.json","handlingStrategy":"validation","validationCode":"jq empty new-config.json && jq -e 'has(\"Addresses\") and has(\"Identity\") or true' new-config.json && head -c 1 new-config.json | grep -q '{' && echo \"looks like JSON config\"","typeGuard":null,"tryCatchPattern":"var newCfg config.Config\nif err := json.NewDecoder(file).Decode(&newCfg); err != nil {\n    return fmt.Errorf(\"failed to decode file as config: %w\", err) // preserve the real cause\n}","preventionTips":["Validate the file with `jq empty` before `ipfs config replace`","Build the replacement from `ipfs config show` output, not hand-written YAML/TOML","Check the file starts with '{' — HTML error pages or empty files fail here","Keep full configs (not fragments); replace expects a complete config structure"],"tags":["config","json","cli"],"backgroundTag":"config-file-invalid-json","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}