Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Debugging K8s Ingress Challenges with OpenVSCode Server: 302, 404, 503, and WebSocket Issues

Tech May 16 2

Phase 1: Path Mismatch Causes 404

Initial Ingress configuration routes traffic from /vscode to the backend service:

spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: vscode-01
            port:
              number: 8888
        path: /vscode
        pathType: Prefix

Accessing /vscode returns a 404. The backend receives a request for /vscode, but expects /—the application has no configurable base path.

Fix: Rewrite the path to root using:

annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /

Phase 2: 302 Redirect Triggers 503

After path rewriting, the app responds with a 302 redirect to /. The browser follows it, but the Ingress now sees a request for /—a path not defined in any rule—resulting in a 503 Service Unavailable.

Fix: Intercept and rewrite the Location header to preserve the original path prefix:

annotations:
  nginx.ingress.kubernetes.io/configuration-snippet: |
    more_set_headers "Location: $scheme://$http_host/vscode/";

Phase 3: Static Assets Fail with 503

After resolving the redirect loop, front end assets like /stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1/static/... return 503. Why? The global rewrite-target: / strips all path segments, so these requests never reach the backend with their original paths.

Fix: Define a separate Ingress rule for static assets using ImplementationSpecific path matching:

spec:
  rules:
  - http:
      paths:
      - path: /stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1/static/(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: vscode-01
            port:
              number: 8888

Phase 4: Cookie Scope Causes 403

Static assets now load, but subsequent requests to /vscode/xxx return 403. Inspection via port-forward and tcpdump reveals missing cookies.

The app sets a cookie with path /, but after the redirect, the browser sends it only for paths under /vscode. Since static assets reside under a completely different path prefix, the cookie is not included.

Fix: Align the entire application’s exposed path to match the static asset prefix. Move the Ingress rule from /vscode to /stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1:

spec:
  rules:
  - http:
      paths:
      - path: /stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1/
        pathType: ImplementationSpecific
        backend:
          service:
            name: vscode-01
            port:
              number: 8888

annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /
  nginx.ingress.kubernetes.io/use-regex: "true"
  nginx.ingress.kubernetes.io/configuration-snippet: |
    more_set_headers "Location: $scheme://$http_host/stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1/";

Now all requests originate from the same base path, and cookies are corrrectly scoped.

Phase 5: WebSocket Connection Drops (1006)

After fixing cookies, the UI loads—but WebSocket connections fail with code 1006 (abnormal closure). Inspection shows the WS endpoint is requested at:

wss://example.com/stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1

But our rule matches only /stable-.../ (with trailing slash). The client omits the trailing slash, so the path doesn’t match.

Fix: Update the path pattern to accept both cases:

spec:
  rules:
  - http:
      paths:
      - path: /stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1(/?|$)
        pathType: ImplementationSpecific
        backend:
          service:
            name: vscode-01
            port:
              number: 8888

This pattern matches either a trailing slash or end-of-string, ensuring WebSocket upgrade requests are correctly routed and rewritten to / for the backend.

Final State

With all rule in place, the application is accessible at:

https://example.com/stable-487e0b6eb726a84faf6b1a95c68a092fba078fd1/?tkn=eomdZNpW

Redirects, static assets, cookies, and WebSockets all function as expected. The Ingress now correctly mediates between the application’s rigid path assumptions and external routing requirements.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.