hashicorp/terraform · critical
Unknown kind: %s
Error message
Unknown kind: %s
What it means
Panics in ResourceConfig.get (resource.go:410) while walking a dotted key path through raw config via reflection. The switch handles only Map, Slice, and String kinds; any other reflect.Kind (struct, int, bool, pointer) in the raw config tree panics.
Source
Thrown at internal/legacy/terraform/resource.go:410
return nil, false
}
if int(i) < 0 || int(i) >= cv.Len() {
return nil, false
}
current = cv.Index(int(i)).Interface()
}
case reflect.String:
// This happens when map keys contain "." and have a common
// prefix so were split as path components above.
actualKey := strings.Join(parts[i-1:], ".")
if prevMap, ok := previous.(map[string]interface{}); ok {
v, ok := prevMap[actualKey]
return v, ok
}
return nil, false
default:
panic(fmt.Sprintf("Unknown kind: %s", cv.Kind()))
}
}
return current, true
}
// unknownCheckWalker
type unknownCheckWalker struct {
Unknown bool
}
func (w *unknownCheckWalker) Primitive(v reflect.Value) error {
if v.Interface() == hcl2shim.UnknownVariableValue {
w.Unknown = true
}
return nil
}View on GitHub (pinned to c9def3e214)
Solutions
- Ensure raw config values are only map[string]interface{}, []interface{}, or string.
- Build raw values via hcl2shim rather than hand-constructing native Go structs.
- Never inject pointers or structs into ResourceConfig.Raw/Config.
Example fix
// before
cfg.Raw = map[string]interface{}{"x": MyStruct{...}}
// after
cfg.Raw = map[string]interface{}{"x": map[string]interface{}{"a": "1"}} Defensive patterns
Strategy: validation
Validate before calling
func rawConfigWalkable(raw interface{}) error {
switch v := raw.(type) {
case map[string]interface{}:
for _, c := range v { if err := rawConfigWalkable(c); err != nil { return err } }
case []interface{}:
for _, c := range v { if err := rawConfigWalkable(c); err != nil { return err } }
case string, nil:
default:
return fmt.Errorf("unsupported raw kind %T in config", raw)
}
return nil
} Type guard
func isWalkableKind(raw interface{}) bool {
switch raw.(type) {
case map[string]interface{}, []interface{}, string, nil: return true
}
return false
} Prevention
- Keep raw config to map/slice/string only.
- Build raw values via hcl2shim, not native structs.
- Never inject pointers/structs into ResourceConfig.Raw.
When it happens
Trigger: Calling ResourceConfig.Get(k) where the raw config value at some path component is a Go struct, primitive (bool/int), or pointer — i.e. raw config not in the map/slice/string shape normally produced by hcl2shim.
Common situations: Custom code injecting non-standard Go values into ResourceConfig.Raw, schema/config corruption, or test fixtures using wrong Go types.
Related errors
- missing field in set: %s.%s
- set item just set doesn't exist
- invalid index value %q
- argument %q is required
- invalid value for %q: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/c96fb411a2ef9058.
Report an issue: GitHub.