caddy-https-troubleshoot
npx skills add https://github.com/dawiddutoit/custom-claude --skill caddy-https-troubleshoot
Agent 安装分布
Skill 文档
Troubleshoot HTTPS Skill
Systematic diagnosis and resolution of HTTPS/SSL certificate issues in the Caddy reverse proxy with Cloudflare DNS-01 challenge.
Quick Start
Run the diagnostic script to identify issues:
/home/dawiddutoit/projects/network/.claude/skills/troubleshoot-https/scripts/diagnose-https.sh
Or follow the step-by-step diagnosis in Instructions.
Table of Contents
- When to Use This Skill
- What This Skill Does
- Instructions
- 3.1 Check API Key Configuration
- 3.2 Verify Cloudflare DNS Plugin
- 3.3 Analyze Caddy Logs
- 3.4 Validate Caddyfile Syntax
- 3.5 Test Certificate Validity
- 3.6 Diagnose Specific Error
- 3.7 Apply Fix
- Supporting Files
- Expected Outcomes
- Common Error Reference
- Requirements
- Red Flags to Avoid
When to Use This Skill
Explicit Triggers:
- “HTTPS not working”
- “SSL certificate error”
- “Certificate not obtained”
- “Caddy keeps restarting”
- “Fix HTTPS certificates”
- “Invalid format for Authorization header”
Implicit Triggers:
- Browser shows “Your connection is not private”
- Services accessible via HTTP but not HTTPS
- Caddy container in restart loop
- New domain not getting certificate
Debugging Triggers:
- “Why is my certificate expired?”
- “Why can’t Caddy get a certificate?”
- “Cloudflare DNS challenge failing”
What This Skill Does
- Checks API Key – Verifies CLOUDFLARE_API_KEY is set and passed to container
- Verifies Plugin – Confirms Cloudflare DNS plugin is compiled into Caddy
- Analyzes Logs – Searches for certificate errors in Caddy logs
- Validates Config – Tests Caddyfile syntax
- Tests Certificates – Checks certificate validity for each domain
- Identifies Error – Matches symptoms to known issues
- Provides Fix – Gives specific commands to resolve the issue
Instructions
3.1 Check API Key Configuration
Step 1: Verify API key is set in .env
grep "CLOUDFLARE_API_KEY" /home/dawiddutoit/projects/network/.env | head -1
Expected: CLOUDFLARE_API_KEY="Xv5MOdOT... (starts with alphanumeric, not v4:)
Step 2: Verify API key is passed to container
docker exec caddy env | grep CLOUDFLARE_API_KEY
Expected: Shows the API key value (not empty)
If empty or missing:
# Recreate container to pick up .env changes
docker compose -f /home/dawiddutoit/projects/network/docker-compose.yml up -d --force-recreate caddy
Key distinction:
- API Token format:
Xv5MOdOT...(alphanumeric string) – CORRECT - Global API Key format:
v4:...or long hex string – WRONG
3.2 Verify Cloudflare DNS Plugin
docker exec caddy caddy list-modules | grep cloudflare
Expected: dns.providers.cloudflare
If not present: Plugin not compiled into Caddy. Rebuild:
cd /home/dawiddutoit/projects/network && \
docker compose build --no-cache caddy && \
docker compose up -d --force-recreate caddy
3.3 Analyze Caddy Logs
Check for certificate-related messages:
docker logs caddy 2>&1 | grep -i -E "certificate|error|failed|invalid" | tail -30
Look for success messages:
docker logs caddy 2>&1 | grep "certificate obtained successfully"
Expected for each domain: certificate obtained successfully {"identifier": "domain.temet.ai"}
3.4 Validate Caddyfile Syntax
docker exec caddy caddy validate --config /etc/caddy/Caddyfile
Expected: Valid configuration (no errors)
If syntax error:
- Read the Caddyfile to identify the error
- Fix the syntax issue
- Reload Caddy
3.5 Test Certificate Validity
Test a single domain:
echo | openssl s_client -servername pihole.temet.ai -connect pihole.temet.ai:443 2>/dev/null | openssl x509 -noout -dates -issuer
Expected output:
notBefore=<date>
notAfter=<date>
issuer=C = US, O = Let's Encrypt, CN = R3
Test all domains:
for domain in pihole jaeger langfuse sprinkler ha; do
echo "=== $domain.temet.ai ==="
echo | openssl s_client -servername $domain.temet.ai -connect $domain.temet.ai:443 2>/dev/null | \
openssl x509 -noout -dates 2>&1 || echo "FAILED to get certificate"
echo
done
3.6 Diagnose Specific Error
Match error message to diagnosis:
| Error Message | Diagnosis | Go to Fix |
|---|---|---|
Invalid format for Authorization header |
Using Global API Key instead of API Token | Fix A |
missing API token |
Environment variable not set | Fix B |
unknown directive 'dns' |
Cloudflare plugin not compiled | Fix C |
certificate obtain error |
Rate limit or DNS propagation | Fix D |
403 Forbidden from Cloudflare |
API token lacks permissions | Fix E |
| Container restart loop | Caddyfile syntax error | Fix F |
3.7 Apply Fix
Fix A: Wrong API Key Type
The error “Invalid format for Authorization header” means you’re using the Global API Key instead of an API Token.
-
Create new API Token:
- Go to: https://dash.cloudflare.com/profile/api-tokens
- Click “Create Token”
- Select template: “Edit zone DNS”
- Zone Resources: Include -> Specific zone -> temet.ai
- Click “Continue to summary” -> “Create Token”
-
Update .env:
# Edit .env and replace CLOUDFLARE_API_KEY with the new token nano /home/dawiddutoit/projects/network/.env -
Recreate Caddy:
docker compose -f /home/dawiddutoit/projects/network/docker-compose.yml up -d --force-recreate caddy -
Verify:
docker logs caddy 2>&1 | grep "certificate obtained successfully"
Fix B: Environment Variable Not Set
-
Verify .env has the key:
grep CLOUDFLARE_API_KEY /home/dawiddutoit/projects/network/.env -
Verify docker-compose.yml passes it:
grep -A5 "caddy:" /home/dawiddutoit/projects/network/docker-compose.yml | grep CLOUDFLARE -
Recreate container:
docker compose -f /home/dawiddutoit/projects/network/docker-compose.yml up -d --force-recreate caddy
Fix C: Cloudflare Plugin Not Compiled
cd /home/dawiddutoit/projects/network && \
docker compose build --no-cache caddy && \
docker compose up -d --force-recreate caddy
Build takes approximately 5 minutes on Raspberry Pi.
Fix D: Rate Limit or DNS Propagation
-
Wait 5 minutes for DNS propagation
-
Restart Caddy:
docker compose -f /home/dawiddutoit/projects/network/docker-compose.yml restart caddy -
If still failing, check Let’s Encrypt rate limits:
- Limit: 50 certificates per domain per week
- Check: https://crt.sh/?q=temet.ai
Fix E: API Token Missing Permissions
- Go to: https://dash.cloudflare.com/profile/api-tokens
- Find your token and click “Edit”
- Verify permissions:
- Zone -> DNS -> Edit (required)
- Zone Resources -> Include -> Specific zone -> temet.ai
- If missing, create new token with correct permissions
Fix F: Caddyfile Syntax Error
-
Check error in logs:
docker logs caddy 2>&1 | tail -50 -
Validate Caddyfile:
docker exec caddy caddy validate --config /etc/caddy/Caddyfile -
Common syntax issues:
- Missing closing braces
} - Invalid directive names
- Wrong environment variable syntax
- Missing closing braces
-
Fix the Caddyfile and reload:
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
Supporting Files
| File | Purpose |
|---|---|
references/reference.md |
Complete error reference, API token creation guide, rate limit details |
scripts/diagnose-https.sh |
Automated diagnostic script |
Expected Outcomes
Success:
- All diagnostic checks pass
certificate obtained successfullyfor each domain- HTTPS working with valid Let’s Encrypt certificates
- Certificate shows issuer:
C = US, O = Let's Encrypt
Partial Success:
- Issue identified but fix requires manual action (e.g., create new API token)
- Certificate pending (DNS propagation in progress)
Failure Indicators:
- API key format is wrong (Global API Key vs API Token)
- Cloudflare plugin not compiled into Caddy
- Caddyfile syntax errors blocking startup
- Let’s Encrypt rate limit exceeded
Common Error Reference
| Error | Cause | Quick Fix |
|---|---|---|
Invalid format for Authorization header |
Wrong API key type (Global vs Token) | Create new API Token with “Edit zone DNS” template |
missing API token |
Env var not passed to container | docker compose up -d --force-recreate caddy |
unknown directive 'dns' |
Plugin not compiled | docker compose build --no-cache caddy |
certificate obtain error |
Rate limit or DNS delay | Wait 5 minutes, restart Caddy |
403 Forbidden |
Token lacks DNS edit permission | Check/update token permissions |
| Container restart loop | Caddyfile syntax error | Check logs, fix syntax, reload |
Requirements
- Docker running with Caddy container
- Valid Cloudflare API Token with “Edit zone DNS” permission
.envfile withCLOUDFLARE_API_KEYset- Internet access for Cloudflare API calls
Red Flags to Avoid
- Do not use Global API Key (format:
v4:...or long hex) – use API Token instead - Do not skip verifying the plugin is compiled before troubleshooting further
- Do not delete caddy_data volume unless absolutely necessary (certificates stored there)
- Do not exceed Let’s Encrypt rate limits (50 certs/domain/week)
- Do not forget to recreate container after .env changes
- Do not use
--no-verifyto bypass certificate errors - Do not commit API tokens to git
Notes
- Certificates are stored in Docker volume
network_caddy_data - Certificates auto-renew 30 days before expiry
- DNS-01 challenge allows certificates for internal-only services
- Caddy checks renewals every 12 hours
- Build with
--no-cacheif plugin changes aren’t taking effect - API Token (not Global API Key) is required for Caddy Cloudflare DNS plugin