ipfs/kubo · error
%s key is not a map
Error message
%s key is not a map
What it means
CheckKey() walks a dotted config path (e.g. "Addresses.API") through nested maps in the config structure. If an intermediate segment resolves to a value that is not a map (and not nil), the path cannot be descended further and this error names the deepest valid prefix of the path.
Source
Thrown at config/config.go:247
func CheckKey(key string) error {
conf := Config{}
// Convert an empty config to a map without JSON.
cursor := ReflectToMap(&conf)
// Parse the key and verify it's presence in the map.
var ok bool
var mapCursor map[string]any
parts := strings.Split(key, ".")
for i, part := range parts {
mapCursor, ok = cursor.(map[string]any)
if !ok {
if cursor == nil {
return nil
}
path := strings.Join(parts[:i], ".")
return fmt.Errorf("%s key is not a map", path)
}
cursor, ok = mapCursor[part]
if !ok {
// If the config sections is a map, validate against the default entry.
if cursor, ok = mapCursor["*"]; ok {
continue
}
path := strings.Join(parts[:i+1], ".")
return fmt.Errorf("%s not found", path)
}
}
return nil
}
View on GitHub (pinned to 329838acdf)
Solutions
- Correct the dotted path so each prefix names a config section (map), not a leaf value
- Print/inspect the config (ipfs config) to verify the actual nesting at the reported prefix
- Stop the path at the reported prefix and set the leaf value directly instead
Example fix
// before err := SetConfigKey(cfg, "Addresses.API.extra", val) // Addresses.API is a string // after err := SetConfigKey(cfg, "Addresses.API", val)
Defensive patterns
Strategy: validation
Validate before calling
// Verify each dotted prefix names an existing section before descending
func pathIsSection(cfg *config.Config, dotted string) bool {
cur := any(cfg)
for _, part := range strings.Split(dotted, ".") {
m, ok := cur.(map[string]any)
if !ok {
return false
}
cur, ok = m[part]
if !ok {
return false
}
}
_, isMap := cur.(map[string]any)
return isMap
} Type guard
func isSection(v any) bool {
_, ok := v.(map[string]any)
return ok
} Try / catch
if err := config.CheckKey(cfg, key); err != nil {
if strings.Contains(err.Error(), "key is not a map") {
// path crosses a leaf value: correct the key or write the leaf directly
return fmt.Errorf("invalid config path %q: %w", key, err)
}
return err
} Prevention
- Validate dotted keys with `ipfs config show` structure before automating writes
- Never append extra segments to a key that already names a leaf value
- Keep a constant list of valid key paths in scripts instead of building them dynamically
When it happens
Trigger: Calling CheckKey or SetConfigKey with a dotted key where an intermediate segment names a scalar value, e.g. "Addresses.API.Sub" when Addresses.API is a string.
Common situations: Typo in the key path causing traversal into a leaf value; config schema change making a formerly-nested section scalar; automation scripts building paths dynamically from bad input.
Related errors
- %s not found
- private network does not work with Routing.Type=auto. Update
- Provide.Strategy='flat' is no longer supported. Use 'all' in
- invalid configuration: Provide.DHT.MaxWorkers cannot be 0 wh
- Routing.Type=delegated does not support content providing. S
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/50d6e050e115c0a6.
Report an issue: GitHub.