kataras/iris · error
unsupported type of map: %T
Error message
unsupported type of map: %T
What it means
AllowUsers accepts users as a map[string]string, map[string]any, a slice of maps, or a slice of User-like structs. This panic fires when the `users` argument is a map whose key/value types are neither string/string nor string/any (e.g. map[int]string). It is a deliberate fail-fast at middleware construction time so a bad configuration never reaches serving.
Source
Thrown at middleware/basicauth/user.go:128
}
}
case reflect.Map:
elem := v.Interface()
switch m := elem.(type) {
case map[string]string:
return userMap(m, opts...)
case map[string]any:
username, password, ok := mapUsernameAndPassword(m)
if !ok {
break
}
cp[username] = &user{
password: password,
ref: m,
}
default:
panic(fmt.Sprintf("unsupported type of map: %T", users))
}
default:
panic(fmt.Sprintf("unsupported type: %T", users))
}
options := toUserAuthOptions(opts)
return func(_ *context.Context, username, password string) (any, bool) {
if u, ok := cp[username]; ok { // fast map access,
if options.ComparePassword(u.password, password) {
return u.ref, true
}
}
return nil, false
}
}
View on GitHub (pinned to 7bedaf55a0)
Solutions
- Convert the map to map[string]string (or map[string]any) before calling AllowUsers, e.g. via a loop or json round-trip.
- If usernames are numeric keys, convert them to strings with strconv when building the map.
- If users come from a struct list, pass the slice of structs instead of a map so the Slice branch is used.
Example fix
// before
users := map[int]string{1: "pass"}
h := basicauth.Default(basicauth.Options{Allow: basicauth.AllowUsers(users)})
// after
users := map[string]string{"admin": "pass"}
h := basicauth.Default(basicauth.Options{Allow: basicauth.AllowUsers(users)}) Defensive patterns
Strategy: type-guard
Validate before calling
switch users.(type) {
case map[string]string, map[string]any:
// ok
default:
panic(fmt.Sprintf("AllowUsers: unsupported map type %T", users))
} Type guard
func isSupportedUsersMap(v any) bool {
switch v.(type) {
case map[string]string, map[string]any:
return true
}
return false
} Try / catch
// panics are not recoverable per-call idiom here; guard before:
if !isSupportedUsersMap(users) { log.Fatalf("unsupported users type %T", users) }
allow := basicauth.AllowUsers(users) Prevention
- Always declare the users map as map[string]string or map[string]any explicitly.
- Convert config-driven maps with a small adapter function before passing to AllowUsers.
- Add a startup test that constructs the middleware with the production users value.
When it happens
Trigger: Calling AllowUsers with a map other than map[string]string or map[string]any, such as AllowUsers(map[int]string{1: "pass"}) or a typed map alias like map[string][]byte. Non-map, non-slice values instead hit the sibling "unsupported type" panic at line 131.
Common situations: Building the users map from config where usernames were parsed as ints; using a custom map type (type Users map[string]Secret) whose value type is not string/any; passing a nil interface typed as a map with non-string keys.
Related errors
- unsupported type: %T
- err
- iris: switch: hosts: invalid target type: %T
- panic(err)
- unexpected "fsOrDir" argument type of %T (string or http.Fil
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/e2db692fdb3a13b7.
Report an issue: GitHub.