tailscale/tailscale · error

unexpected/unsupported %s contents

Error message

unexpected/unsupported %s contents

What it means

updateDebianAptSourcesList rewrites /etc/apt/sources.list.d/tailscale.list when switching tracks and expects its rewrite to change exactly one line (or leave the file equivalent). This error means the pass produced zero or multiple changes, so the file no longer matches the shape the updater understands; it bails instead of guessing.

Source

Thrown at clientupdate/clientupdate.go:582

				if bytes.Equal(m, trackURLPrefix) {
					hadCorrect = true
				} else {
					changes++
				}
				return trackURLPrefix
			})
		}
		buf.Write(line)
		buf.WriteByte('\n')
	}
	if hadCorrect || (changes == 1 && bytes.Equal(bytes.TrimSpace(was), bytes.TrimSpace(buf.Bytes()))) {
		// Unchanged or close enough.
		return was, nil
	}
	if changes != 1 {
		// No changes, or an unexpected number of changes (what?). Bail.
		// They probably editted it by hand and we don't know what to do.
		return nil, fmt.Errorf("unexpected/unsupported %s contents", aptSourcesFile)
	}
	return buf.Bytes(), nil
}

func (up *Updater) archPackageInstalled() bool {
	err := exec.Command("pacman", "--query", "tailscale").Run()
	return err == nil
}

func (up *Updater) updateArchLike() error {
	// Arch maintainer asked us not to implement "tailscale update" or
	// auto-updates on Arch-based distros:
	// https://github.com/tailscale/tailscale/issues/6995#issuecomment-1687080106
	return errors.New(`individual package updates are not supported on Arch-based distros, only full-system updates are: https://wiki.archlinux.org/title/System_maintenance#Partial_upgrades_are_unsupported.
you can use "pacman --sync --refresh --sysupgrade" or "pacman -Syu" to upgrade the system, including Tailscale.`)
}

func (up *Updater) updateNixos() error {

View on GitHub (pinned to cfe32b8be6)

Solutions

  1. Replace the file with a single canonical line: deb https://pkgs.tailscale.com/<suite>/<track> <suite> main
  2. Then rerun 'tailscale update'
  3. Or manage the sources file yourself (Ansible, scripts) and stop relying on 'tailscale update' to switch tracks on Debian

Example fix

# before (/etc/apt/sources.list.d/tailscale.list)
deb https://pkgs.tailscale.com/stable/debian bookworm main
deb [arch=amd64] https://mirror.example.com/tailscale bookworm main

# after
deb https://pkgs.tailscale.com/stable/debian bookworm main
Defensive patterns

Strategy: validation

Validate before calling

func aptSourcesFileIsCanonical(path string) bool {
	data, err := os.ReadFile(path)
	if err != nil {
		return false
	}
	debLines := 0
	for _, l := range strings.Split(string(data), "\n") {
		if strings.HasPrefix(strings.TrimSpace(l), "deb ") {
			debLines++
		}
	}
	return debLines == 1
}

if !aptSourcesFileIsCanonical(aptSourcesFile) {
	// Refuse track-switching updates; fix or manage the file manually.
}

Try / catch

err := up.Update()
if err != nil && strings.Contains(err.Error(), "unexpected/unsupported") && strings.Contains(err.Error(), "tailscale.list") {
	// Reset the sources file to one canonical deb line, then re-run the update.
}

Prevention

When it happens

Trigger: Hand-edited tailscale.list: extra deb lines, rewritten URLs, reformatted comments, or options added to the deb stanza; a file previously repaired manually after past repo changes.

Common situations: Admins pinning internal mirrors or adding arch filters; config management that rewrote the file; residue from older repo layouts.

Related errors


AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15). Data as JSON: /api/errors/bb49055b6015b2e6. Report an issue: GitHub.