{"record":{"id":"01ee08ed586ee8f5","repo":"tailscale/tailscale","slug":"only-implemented-on-synology-01ee08","errorCode":null,"errorMessage":"only implemented on Synology","messagePattern":"only implemented on Synology","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/tailscale/cli/configure-synology.go","lineNumber":74,"sourceCode":"This command is intended to run at boot as root on a Synology device to\ncreate the /dev/net/tun device and give the tailscaled binary permission\nto use it.\n\nSee: https://tailscale.com/s/synology-outbound\n`),\n\t\tFlagSet: (func() *flag.FlagSet {\n\t\t\tfs := newFlagSet(\"synology\")\n\t\t\treturn fs\n\t\t})(),\n\t}\n}\n\nfunc runConfigureSynology(ctx context.Context, args []string) error {\n\tif len(args) > 0 {\n\t\treturn errors.New(\"unknown arguments\")\n\t}\n\tif runtime.GOOS != \"linux\" || distro.Get() != distro.Synology {\n\t\treturn errors.New(\"only implemented on Synology\")\n\t}\n\tif uid := os.Getuid(); uid != 0 {\n\t\treturn fmt.Errorf(\"must be run as root, not %q (%v)\", os.Getenv(\"USER\"), uid)\n\t}\n\thi := hostinfo.New()\n\tisDSM6 := strings.HasPrefix(hi.DistroVersion, \"6.\")\n\tisDSM7 := strings.HasPrefix(hi.DistroVersion, \"7.\")\n\tif !isDSM6 && !isDSM7 {\n\t\treturn fmt.Errorf(\"unsupported DSM version %q\", hi.DistroVersion)\n\t}\n\tif _, err := os.Stat(\"/dev/net/tun\"); os.IsNotExist(err) {\n\t\tif err := os.MkdirAll(\"/dev/net\", 0755); err != nil {\n\t\t\treturn fmt.Errorf(\"creating /dev/net: %v\", err)\n\t\t}\n\t\tif out, err := exec.Command(\"/bin/mknod\", \"/dev/net/tun\", \"c\", \"10\", \"200\").CombinedOutput(); err != nil {\n\t\t\treturn fmt.Errorf(\"creating /dev/net/tun: %v, %s\", err, out)\n\t\t}\n\t}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/cmd/tailscale/cli/configure-synology.go#L56-L92","documentation":"runConfigureSynology requires runtime.GOOS == linux AND distro.Get() == distro.Synology before it will create /dev/net/tun and adjust outbound settings. The command manipulates DSM-specific system state, so on ordinary Linux or non-Linux hosts it refuses immediately with this error.","triggerScenarios":"Executing `tailscale configure synology` anywhere other than a Synology DSM host — a desktop, a Debian server, or an environment where distro.Get() fails to identify DSM.","commonSituations":"Running the setup from a workstation by mistake; a containerized tailscale CLI on the NAS that cannot see DSM markers; testing in a VM that mimics but is not DSM.","solutions":["SSH into the Synology NAS and run `sudo tailscale configure synology` there","Verify DSM detection: `cat /etc/VERSION` should show a DSM build","If the CLI is containerized on the NAS, run it from the host shell instead"],"exampleFix":"# before\n$ tailscale configure synology\nerror: only implemented on Synology\n\n# after\nnas$ sudo tailscale configure synology","handlingStrategy":"validation","validationCode":"[ \"$(uname -s)\" = \"Linux\" ] || { echo 'needs Linux'; exit 1; }\ngrep -q synology /etc/VERSION 2>/dev/null || { echo 'only on Synology DSM hosts'; exit 1; }\nsudo tailscale configure synology","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve the synology subcommand for the NAS host shell","Verify DSM markers (/etc/VERSION) when distro detection is in doubt","Keep host-specific configuration out of generic provisioning scripts"],"tags":["cli","platform","synology","distro-detection"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}