ipfs/kubo · error
failed to unmarshal json. %s
Error message
failed to unmarshal json. %s
What it means
When `ipfs config <key> <value> --json` is given, Kubo parses the value string with encoding/json into an `any` before storing it. If the string is not valid JSON, the raw parse error is wrapped as 'failed to unmarshal json. %s' and the config is left unchanged.
Source
Thrown at core/commands/config.go:152
id, err := nodePeerID(r)
if err != nil {
return err
}
got, err := peer.Decode(candidate)
if err != nil || got != id {
return errors.New("cannot set Identity.PeerID to a value that does not match the node's private key; use 'ipfs key rotate' to change the node identity")
}
output, err = setConfig(r, key, id.String())
if err != nil {
return err
}
return cmds.EmitOnce(res, output)
}
if parseJSON, _ := req.Options[configJSONOptionName].(bool); parseJSON {
var jsonVal any
if err := json.Unmarshal([]byte(value), &jsonVal); err != nil {
err = fmt.Errorf("failed to unmarshal json. %s", err)
return err
}
output, err = setConfig(r, key, jsonVal)
} else if isbool, _ := req.Options[configBoolOptionName].(bool); isbool {
output, err = setConfig(r, key, value == "true")
} else {
output, err = setConfig(r, key, value)
}
} else {
// Check if user wants to expand auto values for getter
expandAuto, _ := req.Options[configExpandAutoName].(bool)
if expandAuto {
output, err = getConfigWithAutoExpand(r, key)
} else {
output, err = getConfig(r, key)
}
}View on GitHub (pinned to 329838acdf)
Solutions
- Validate the value first: `echo '<value>' | jq empty` and only then pass it to ipfs config --json
- Quote the value as a whole: ipfs config Addresses.API '"/ip4/127.0.0.1/tcp/5001"' --json
- If the value is a plain string/boolean, drop --json (or use --bool) and pass it raw
- Inspect the exact parse error after 'failed to unmarshal json.' — it names the byte offset and problem
Example fix
// before $ ipfs config Datastore.StorageMax 10GB --json failed to unmarshal json. invalid character '1'... // after $ ipfs config Datastore.StorageMax '"10GB"' --json
Defensive patterns
Strategy: validation
Validate before calling
echo "$value" | jq empty && ipfs config "$key" "$value" --json
Type guard
func validJSON(s string) bool { var v any; return json.Unmarshal([]byte(s), &v) == nil } Try / catch
if err := run("ipfs", "config", key, val, "--json"); err != nil {
if strings.Contains(err.Error(), "failed to unmarshal json") {
// fall back: pass as plain string without --json
}
} Prevention
- Pipe values through `jq empty` before passing with --json
- Remember bare strings/numbers still need JSON quoting ('"10GB"', '"true"')
- Use single quotes around the whole value in shells to preserve inner double quotes
- Prefer --bool for booleans and plain arguments for strings instead of --json
When it happens
Trigger: `ipfs config <key> <value> --json` where value is not valid JSON: single quotes (shell-stripped), unquoted bare words (`ipfs config Datastore.StorageMax 10GB --json`), unquoted keys, trailing commas, or shell-mangled quotes in a nested object.
Common situations: Shell quoting pitfalls: `--json '{"a":1}'` losing inner quotes, forgetting that bare strings must be JSON-quoted (`--json '"true"'`), scripts passing env vars that contain unescaped content; also users of the RPC `/api/v0/config` with the json flag.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- failed to set config value: %s (maybe use --json?)
- failed to decode file as config
- invalid configuration profile: %s
- invalid provide strategy: empty token in %q
- unknown provide strategy token: %q in %q
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/dece020e782fc02a.
Report an issue: GitHub.