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

  1. Open the config and make every element of upstreams a quoted string ("dns://…")
  2. Re-export the config from AdGuard Home itself so upstream entries are strings
  3. 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

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


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/4f24f7dde3473eb1. Report an issue: GitHub.