{"record":{"id":"d7fa966a9aeb5cfe","repo":"d2lang/d2","slug":"expected-status-200-but-got-d-s","errorCode":null,"errorMessage":"expected status 200 but got %d %s","messagePattern":"expected status 200 but got (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/imgbundler/imgbundler.go","lineNumber":233,"sourceCode":"\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"en-US,en;q=0.9\")\n\treq.Header.Set(\"Accept-Encoding\", \"gzip, deflate, br\")\n\treq.Header.Set(\"DNT\", \"1\")\n\treq.Header.Set(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Sec-Fetch-Dest\", \"image\")\n\treq.Header.Set(\"Sec-Fetch-Mode\", \"no-cors\")\n\treq.Header.Set(\"Sec-Fetch-Site\", \"cross-site\")\n\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tl.Debug(fmt.Sprintf(\"fetched %s remotely - response code %v\", string(href), resp.StatusCode))\n\tif resp.StatusCode != 200 {\n\t\treturn nil, \"\", fmt.Errorf(\"expected status 200 but got %d %s\", resp.StatusCode, resp.Status)\n\t}\n\tr := http.MaxBytesReader(nil, resp.Body, maxImageSize)\n\tbuf, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tcontentType := resp.Header.Get(\"Content-Type\")\n\tcontentEncoding := resp.Header.Get(\"Content-Encoding\")\n\tif contentEncoding != \"\" {\n\t\tbuf, err = decodeContentEncoding(buf, contentEncoding)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", fmt.Errorf(\"failed to decode %q response for %s: %w\", contentEncoding, href, err)\n\t\t}\n\t}\n\tl.Debug(fmt.Sprintf(\"fetched content type: %s, Content length: %d bytes\", contentType, len(buf)))\n\n\treturn buf, contentType, nil\n}","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/lib/imgbundler/imgbundler.go#L215-L251","documentation":"httpGet fetches a remote image over HTTP and expects a successful response. When the HTTP status code is anything other than 200, it aborts and returns this error carrying the actual status code and status text. The library only accepts a plain 200 — redirects are already followed by the client, but soft errors like 404/403/500 are surfaced here.","triggerScenarios":"The remote image URL returned a non-200 status: 404 (image moved/deleted), 403 (hotlink protection, missing auth, UA blocking), 5xx (origin/CDN error), or 429 (rate limiting). Raised in httpGet, called by worker during page image bundling.","commonSituations":"Bundling pages whose images point at expired CDN links, sites blocking non-browser user agents, signed URLs whose tokens expired, or origins rate-limiting the bundler after many requests.","solutions":["Open the URL in a browser/curl to confirm the actual status and fix or replace the image URL","Set a browser-like User-Agent and any required Referer/auth headers if the origin blocks hotlinking","Retry with backoff on 429/5xx; the cause is transient server-side limiting or failure","If the image is gone, remove it from the page or substitute a valid hosted copy"],"exampleFix":"// before\nresp, _, err := httpGet(ctx, client, href)\n// after\n// Check the URL first; on transient statuses retry\nresp, _, err := httpGet(ctx, client, href)\nif err != nil && (strings.Contains(err.Error(), \"429\") || strings.Contains(err.Error(), \"50\")) {\n\ttime.Sleep(backoff)\n\tresp, _, err = httpGet(ctx, client, href)\n}","handlingStrategy":"retry","validationCode":"resp, err := http.Head(imgURL)\nif err != nil || resp.StatusCode != 200 {\n\treturn fmt.Errorf(\"image %s not fetchable: status %v\", imgURL, resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := httpGet(ctx, client, href); err != nil {\n\tif strings.Contains(err.Error(), \"expected status 200\") {\n\t\t// inspect status code inside message; retry on 429/5xx, skip URL on 404/403\n\t}\n}","preventionTips":["Pre-check image URLs for reachability before bundling","Send a browser-like User-Agent/Referer to avoid hotlink blocks","Use durable, pre-signed or CDN-hosted image URLs with valid expiry","Apply backoff retry for 429/5xx statuses"],"tags":["http","network","go","imgbundler"],"backgroundTag":"http-non-200-status","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}