{"record":{"id":"23f006120b03f9e2","repo":"tailscale/tailscale","slug":"errormessagefrombody-all","errorCode":null,"errorMessage":"errorMessageFromBody(all)","messagePattern":"errorMessageFromBody\\(all\\)","errorType":"http","errorClass":"AccessDeniedError","httpStatus":403,"severity":"error","filePath":"client/local/local.go","lineNumber":172,"sourceCode":"\t\t}\n\t})\n\tif !lc.OmitAuth {\n\t\tif _, token, err := safesocket.LocalTCPPortAndToken(); err == nil {\n\t\t\treq.SetBasicAuth(\"\", token)\n\t\t}\n\t}\n\treturn lc.tsClient.Do(req)\n}\n\nfunc (lc *Client) doLocalRequestNiceError(req *http.Request) (*http.Response, error) {\n\tres, err := lc.DoLocalRequest(req)\n\tif err == nil {\n\t\tif server := res.Header.Get(\"Tailscale-Version\"); server != \"\" && server != envknob.IPCVersion() && onVersionMismatch != nil {\n\t\t\tonVersionMismatch(envknob.IPCVersion(), server)\n\t\t}\n\t\tif res.StatusCode == 403 {\n\t\t\tall, _ := io.ReadAll(res.Body)\n\t\t\treturn nil, &AccessDeniedError{errors.New(errorMessageFromBody(all))}\n\t\t}\n\t\tif res.StatusCode == http.StatusPreconditionFailed {\n\t\t\tall, _ := io.ReadAll(res.Body)\n\t\t\treturn nil, &PreconditionsFailedError{errors.New(errorMessageFromBody(all))}\n\t\t}\n\t\treturn res, nil\n\t}\n\tif ue, ok := err.(*url.Error); ok {\n\t\tif oe, ok := ue.Err.(*net.OpError); ok && oe.Op == \"dial\" {\n\t\t\tpath := req.URL.Path\n\t\t\tpathPrefix, _, _ := strings.Cut(path, \"?\")\n\t\t\treturn nil, fmt.Errorf(\"Failed to connect to local Tailscale daemon for %s; %s Error: %w\", pathPrefix, tailscaledConnectHint(), oe)\n\t\t}\n\t}\n\treturn nil, err\n}\n\ntype errorJSON struct {","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/client/local/local.go#L154-L190","documentation":"Thrown by checkPartitionFits in `tailscale configure flash-appliance`: a GAF member (\"boot.img\" or \"root.img\") has UncompressedSize64 larger than the fixed gokrazy partition it must be written into (disklayout.BootPartitionSizeMB or RootPartitionSizeMB in MB). The CLI refuses to flash because the image would overflow its partition in the GPT layout.","triggerScenarios":"Calling `tailscale configure flash-appliance` with a custom-built GAF whose root.img (or boot.img) exceeds disklayout.RootPartitionSizeMB<<20 (resp. BootPartitionSizeMB<<20) bytes — e.g. you added packages/files to a gokrazy build and the squashfs root grew past the layout's fixed partition size.","commonSituations":"Custom gokrazy builds with extra packages or large assets, flashing an image built for a newer appliance layout with an older CLI whose disklayout constants are smaller, or accidentally zipping the wrong (bigger) artifact into the GAF.","solutions":["Trim the offending member: remove packages/files from your gokrazy build until root.img/boot.img is under the printed limit.","Use the official, unmodified Tailscale appliance GAF image which is guaranteed to fit the layout.","If you genuinely need a bigger root, flash with a gokrazy-native tooling (gok overwrite / gokr-packer) that writes its own partition table instead of the fixed layout, or patch disklayout.RootPartitionSizeMB locally and rebuild the CLI.","Check the printed byte counts to see which member is oversized and by how much before deciding."],"exampleFix":"// before: oversized custom root\n$ unzip -l my.gaf | grep root.img\n  536870912  root.img   # larger than RootPartitionSizeMB<<20\n$ tailscale configure flash-appliance --gaf my.gaf\nError: root.img is 536870912 bytes; gokrazy layout allows up to 524288000\n\n// after: shrink build (remove large assets) and re-pack\ngok build --update=all  # smaller root.img, then re-zip flat\n$ tailscale configure flash-appliance --gaf smaller.gaf --disk /dev/disk2","handlingStrategy":"validation","validationCode":"// check member sizes against the gokrazy layout limits before flashing\nconst bootMax = int64(disklayout.BootPartitionSizeMB) << 20\nconst rootMax = int64(disklayout.RootPartitionSizeMB) << 20\n\nfor _, ck := range []struct{ name string; max int64 }{\n    {\"boot.img\", bootMax}, {\"root.img\", rootMax},\n} {\n    zf := findZipMember(files, ck.name)\n    if zf == nil {\n        return fmt.Errorf(\"GAF is missing %s\", ck.name)\n    }\n    if int64(zf.UncompressedSize64) > ck.max {\n        return fmt.Errorf(\"%s is %d bytes; gokrazy layout allows up to %d\",\n            ck.name, zf.UncompressedSize64, ck.max)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After every custom gokrazy build, compare `unzip -l` member sizes to the limits the CLI prints.","Keep large assets out of boot.img/root.img or host them on the data partition.","Pin the CLI version that matches the appliance image layout you build against."],"tags":["go","tailscale","gokrazy","flash-appliance","disk-layout","capacity"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}