AdguardTeam/AdGuardHome · error
unexpected type of upstream field: %T
Error message
unexpected type of upstream field: %T
What it means
During migration to schema 10, addQUICPorts found an entry in the upstreams array that is not a string. Each upstream must be a YAML string so a QUIC port can be appended; any other YAML type aborts the migration.
Source
Thrown at internal/configmigrate/v10.go:75
return err
} else if ok {
if err = addQUICPorts(ups, quicPort); err != nil {
return err
}
dns["local_ptr_upstreams"] = ups
}
return nil
}
// addQUICPorts inserts a port into each QUIC upstream's hostname in ups if
// those are missing.
func addQUICPorts(ups yarr, port int) (err error) {
for i, uVal := range ups {
u, ok := uVal.(string)
if !ok {
return fmt.Errorf("unexpected type of upstream field: %T", uVal)
}
ups[i] = addQUICPort(u, port)
}
return nil
}
// addQUICPort inserts a port into QUIC upstream's hostname if it is missing.
func addQUICPort(ups string, port int) (withPort string) {
if ups == "" || ups[0] == '#' {
return ups
}
var doms string
withPort = ups
if after, ok := strings.CutPrefix(ups, "[/"); ok {
domsAndUps := strings.Split(after, "/]")View on GitHub (pinned to b41aefbe51)
Solutions
- Open the config and make every element of upstreams a quoted string ("dns://…")
- Re-export the config from AdGuard Home itself so upstream entries are strings
- Retry the migration after fixing the offending entry
Example fix
# before upstreams: - quic://dns.adguard.com - 53 # after upstreams: - quic://dns.adguard.com:853 - "53"
Defensive patterns
Strategy: type-guard
Validate before calling
for _, u := range upstreams {
if _, ok := u.(string); !ok { /* fix: quote all upstream entries */ }
} Type guard
func isStringArray(a []any) bool {
for _, v := range a {
if _, ok := v.(string); !ok { return false }
}
return true
} Try / catch
if err != nil && strings.Contains(err.Error(), "unexpected type of upstream field") { /* quote numeric entries and re-migrate */ } Prevention
- Always quote upstream values in YAML
- Generate configs with the tool itself, not scripts that emit unquoted scalars
When it happens
Trigger: Migrating a config where the dns.upstreams (or equivalent) array contains a non-string element, e.g. `- 53` (int) or a nested mapping `- url: ...`, while QUIC port insertion is applied.
Common situations: Machine-generated or hand-converted configs that emit numbers or objects for upstream entries; configs converted from JSON with lossy typing.
Related errors
- persistent client at index %d: unexpected type %T
- filters: at index %d: expected object, got %T
- unexpected type of %q: %T
- parsing config file for upgrade: %w
- generating new config: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/4f24f7dde3473eb1.
Report an issue: GitHub.