chore: switch agent gone response from 502 to 404 (#23090)

When a user creates a workspace, opens the web terminal, then the
workspace stops but the web terminal remains open the web terminal will
retry the connection. Coder will issue a HTTP 502 Bad Gateway response
when this occurs because coderd cannot connect to the workspace agent,
however this is problematic as any load balancer sitting in front of
Coder sees a 502 and thinks Coder is unhealthy.

The main change is in
https://github.com/coder/coder/pull/23090/changes#diff-bbe3b56ed3532289481a0e977867cd15048b7ca718ce676aae3f3332378eebc2R97,
however the main test and downstream tests are also updated.

This PR changes the response to a [HTTP
404](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/404)
after internal discussion.

<img width="1832" height="1511" alt="image"
src="https://github.com/user-attachments/assets/0baff80d-bb98-4644-89cd-e80c87947098"
/>

Created with the help of Mux, reviewed and tested by a human
This commit is contained in:
Rowan Smith
2026-03-26 00:57:28 +11:00
committed by GitHub
parent 44baac018a
commit c33812a430
3 changed files with 5 additions and 5 deletions
+2 -2
View File
@@ -384,9 +384,9 @@ func TestCSRFExempt(t *testing.T) {
data, _ := io.ReadAll(resp.Body)
_ = resp.Body.Close()
// A StatusBadGateway means Coderd tried to proxy to the agent and failed because the agent
// A StatusNotFound means Coderd tried to proxy to the agent and failed because the agent
// was not there. This means CSRF did not block the app request, which is what we want.
require.Equal(t, http.StatusBadGateway, resp.StatusCode, "status code 500 is CSRF failure")
require.Equal(t, http.StatusNotFound, resp.StatusCode, "status code 500 is CSRF failure")
require.NotContains(t, string(data), "CSRF")
})
}
+1 -1
View File
@@ -1016,7 +1016,7 @@ func Test_ResolveRequest(t *testing.T) {
w := rw.Result()
defer w.Body.Close()
require.Equal(t, http.StatusBadGateway, w.StatusCode)
require.Equal(t, http.StatusNotFound, w.StatusCode)
assertConnLogContains(t, rw, r, connLogger, workspace, agentNameUnhealthy, appNameAgentUnhealthy, database.ConnectionTypeWorkspaceApp, me.ID)
require.Len(t, connLogger.ConnectionLogs(), 1)
+2 -2
View File
@@ -77,7 +77,7 @@ func WriteWorkspaceApp500(log slog.Logger, accessURL *url.URL, rw http.ResponseW
})
}
// WriteWorkspaceAppOffline writes a HTML 502 error page for a workspace app. If
// WriteWorkspaceAppOffline writes a HTML 404 error page for a workspace app. If
// appReq is not nil, it will be used to log the request details at debug level.
func WriteWorkspaceAppOffline(log slog.Logger, accessURL *url.URL, rw http.ResponseWriter, r *http.Request, appReq *Request, msg string) {
if appReq != nil {
@@ -94,7 +94,7 @@ func WriteWorkspaceAppOffline(log slog.Logger, accessURL *url.URL, rw http.Respo
}
site.RenderStaticErrorPage(rw, r, site.ErrorPageData{
Status: http.StatusBadGateway,
Status: http.StatusNotFound,
Title: "Application Unavailable",
Description: msg,
Actions: []site.Action{