Skip to content

[mTLS] Same client certificate assigned to multiple servers: only last configured server works #4601

@wilhelmf-devel

Description

@wilhelmf-devel

Preflight checks

  • I am using the experimental mTLS feature
  • I have reproduced this issue at least once after restarting the app

App platform

iOS

Device and app information

Model Name: iPhone 17 Pro & iPad Air M2 (tested on both devices)
Device Identifier (optional):
OS Version: 26.4.2
App Version (including build number): 2026.4.1 (2026.1904)

Home Assistant environment

Home Assistant Core Version: 2026.4.4
Supervisor Version (if applicable): n/a
Installation Type (HAOS, Container, Core, Supervised): Container
Host OS: Debian 13/Trixie
Reverse Proxy (none/nginx/Traefik/Caddy/Cloudflare/other): Apache 2.4.66-1~deb13u2
TLS Termination Point (HA/proxy/other): proxy

mTLS setup details

Client certificate source (generated by HA/external CA): external CA (self-signed CA, same certificate assigned to all servers)
Client certificate format (PKCS#12/PEM/etc): PKCS#12
Certificate validity window (not before/not after): valid
Signing CA type (public/private/self-signed): self-signed
Server certificate issuer: Let's Encrypt
Full chain served by server? (yes/no/unknown): yes

Failure symptoms

Exact error message shown in app: White screen, then "Verbindung wurde getrennt" / "Connection lost" after timeout
Error code (if any): none shown
When does it fail?: initial connect via external URL (WiFi disabled)
Frequency (always/intermittent): always
Time of most recent failure (with timezone): 2026-05-03 18:00, UTC+2

Steps to reproduce

  1. Configure 3 servers in the app, assign the SAME certificate to all 3 servers in Labs → Client Certificate settings
  2. Disable WiFi to force external URL usage
  3. Open each server in the app

Expected vs actual behavior

Expected: All 3 servers connect successfully, presenting the client certificate during TLS handshake

Actual: Only the last configured server connects. The others show a white screen and "Connection lost" after timeout.
Reverse proxy logs confirm: TCP connection arrives for all servers, but TLS handshake fails for non-working servers (Apache: AH01998 abortive shutdown) — no client certificate is presented.

Key finding: Assigning a unique certificate (same CA, different key pair) to each server resolves the issue completely. This only occurs when the same SecIdentity/p12 is shared across multiple servers.

Additional context

Diagnostic difference worth noting:

  • When NO certificate is configured: app immediately shows a TLS error with connection diagnostics
  • With this bug (same cert, multiple servers): app shows white screen + silent timeout — suggesting the app believes it sent a certificate but did not

Probable cause: the SecIdentity (or derived URLCredential) is stored globally rather than per server. Configuring the same identity for multiple servers overwrites the previous registration. The last configured server "owns" the identity at TLS challenge time.

Workaround: use a unique .p12 per server (same CA accepted by the proxy).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions