Error unquoting TXT/SPF record

1. Output of caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I run Caddy:

provided systemd setup

a. System environment:

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.2 LTS
Release:	20.04
Codename:	focal

b. Command:

sudo systemctl start caddy.service

c. Service/unit/compose file:

n/a

d. My complete Caddy config:

{
    #debug
    on_demand_tls {
        ask http://127.0.0.1:5555/_domain_check
    }
    storage s3 {
        host "s3.amazonaws.com"
        bucket "nope"
        access_key "nope"
        secret_key "nope"
        prefix "nope-certs"
    }
}

:443 {

    # API RELATED CONFIGS

    # allow password reset
    @api_password_reset {
        header_regexp apihost Host api\.(.*)
        path /password_reset*
    }
    handle @api_password_reset {
        redir https://www.{re.apihost.1}{uri} permanent
    }

    # allow activate
    @api_activate {
        header_regexp apihost Host api\.(.*)
        path /activate*
    }
    handle @api_activate {
        redir https://www.{re.apihost.1}{uri} permanent
    }

    # allow admin
    @api_admin {
        header Host api.*
        path /admin*
    }
    handle @api_admin {
        reverse_proxy 127.0.0.1:5001
    }

    # allow crossbar-api-clients
    @api_client {
        header Host api.*
        header User-Agent crossbar-api-client
    }
    handle @api_client {
        reverse_proxy 127.0.0.1:5001 {
		fail_duration 0s
		max_fails 100000
		unhealthy_status 5xx
	}
    }

    # api static assets
    @api_static {
        header Host api.*
        path /static*
    }
    handle @api_static {
        file_server /static/* {
            root /var/www/cb/api/api/
        }
    }

    # api media assets
    @api_media {
        header Host api.*
        path /media*
    }
    handle @api_static {
        file_server /media/* {
            root /var/www/cb/api/api/
        }
    }

    @api_the_rest {
        header Host api.*
    }
    handle @api_the_rest {
        header {
            Content-Type "text/html; charset=UTF-8"
        }
        respond "Forbidden 禁止の" 403
    }

    @new_marketing {
        header Host s.crossbar.org
        header Host local.s.crossbar.org
    }
    @old_marketing {
        header Host a.crossbar.org
        header Host local.a.crossbar.org
    }
    handle @new_marketing {
        reverse_proxy 127.0.0.1:7777
    }
    handle @old_marketing {
        reverse_proxy 127.0.0.1:7777
    }

    @www_crossbar_org {
	header Host www.crossbar.org
    }
    handle @www_crossbar_org {
        redir https://crossbar.org{uri} permanent
    }
    @www_staging_crossbar_org {
	header Host www.staging.crossbar.org
    }
    handle @www_staging_crossbar_org {
        redir https://staging.crossbar.org{uri} permanent
    }

    @www_app {
	header Host crossbar.org
	header Host staging.crossbar.org
    }
    handle @www_app {
        file_server /static/* {
            root /var/www/cb/www/
        }
    }
    handle @www_app {
        reverse_proxy 127.0.0.1:5002
    }

    @app header Host www.*

    # serve static files
    handle @app {
        file_server /static/* {
            root /var/www/cb/app/
        }
    }

    handle @app {
        reverse_proxy 127.0.0.1:5000
    }

    # send non-www to www
    @needs_www {
        not header Host api.*
    }
    handle @needs_www {
        redir https://www.{host}{uri}
    }

    # old domain redirects
    @crossbarhq_root header Host crossbarhq.com
    handle @crossbarhq_root {
        redir https://crossbar.org{uri} permanent
    }
    @crossbarhq_www header Host www.crossbarhq.com
    handle @crossbarhq_www {
        redir https://crossbar.org{uri} permanent
    }

    tls {
        on_demand
        # forcing RSA ciphers and certs
        key_type rsa2048
        issuer zerossl {
            email josh.anyan@nope.org
            propagation_timeout 240s
            timeout 480s
            dns route53 {
                max_retries 10
                aws_profile "default"
            }
        }
        issuer acme {
            email josh.anyan@nope.org
            propagation_timeout 240s
            timeout 480s
            dns route53 {
                max_retries 10
                aws_profile "default"
            }
        }
        ciphers TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_128_CBC_SHA TLS_RSA_WITH_AES_256_CBC_SHA TLS_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384 TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    }

    log {
        output file /tmp/caddy.log {
            roll_size 100MiB
            roll_keep 10
            roll_keep_for 336h
        }
    }
}

3. The problem I’m having:

Some context, I’m using route53 and s3 for storage, see below.
I can successfully generate certs for some domains, but others are consistently failing. The error message I’m receiving is in #4.

$ caddy list-modules
....
  Standard modules: 99

caddy.storage.s3
dns.providers.route53

  Non-standard modules: 2

  Unknown modules: 0

4. Error messages and/or full log output:

2022/10/27 20:36:38.246	INFO	http	waiting on internal rate limiter	{"identifiers": ["a.crossbar.org"], "ca": "https://acme.zerossl.com/v2/DV90", "account": "josh.anyan@nope.org"}
2022/10/27 20:36:38.246	INFO	http	done waiting on internal rate limiter	{"identifiers": ["a.crossbar.org"], "ca": "https://acme.zerossl.com/v2/DV90", "account": "josh.anyan@nope.org"}
2022/10/27 20:36:39.316	INFO	http.acme_client	trying to solve challenge	{"identifier": "a.crossbar.org", "challenge_type": "dns-01", "ca": "https://acme.zerossl.com/v2/DV90"}
2022/10/27 20:36:39.925	ERROR	http.acme_client	cleaning up solver	{"identifier": "a.crossbar.org", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.a.crossbar.org\" (usually OK if presenting also failed)"}
2022/10/27 20:36:40.355	ERROR	tls.obtain	could not get certificate from issuer	{"identifier": "a.crossbar.org", "issuer": "acme.zerossl.com-v2-DV90", "error": "[a.crossbar.org] solving challenges: presenting for challenge: adding temporary record for zone \"crossbar.org.\": Error unquoting TXT/SPF record: invalid syntax (order=https://acme.zerossl.com/v2/DV90/order/l7_UUFOyZlsuPjJ-r3vKTQ) (ca=https://acme.zerossl.com/v2/DV90)"}
2022/10/27 20:36:40.355	INFO	caddy.storage.s3	Load: cb-certs/acme/acme-v02.api.letsencrypt.org-directory/users/josh.anyan@nope.org/josh.anyan.json
2022/10/27 20:36:40.493	INFO	caddy.storage.s3	Load: cb-certs/acme/acme-v02.api.letsencrypt.org-directory/users/josh.anyan@nope.org/josh.anyan.key
2022/10/27 20:36:40.643	INFO	http	waiting on internal rate limiter	{"identifiers": ["a.crossbar.org"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "josh.anyan@nope.org"}
2022/10/27 20:36:40.643	INFO	http	done waiting on internal rate limiter	{"identifiers": ["a.crossbar.org"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "josh.anyan@nope.org"}
2022/10/27 20:36:41.094	INFO	http.acme_client	trying to solve challenge	{"identifier": "a.crossbar.org", "challenge_type": "dns-01", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2022/10/27 20:36:41.598	ERROR	http.acme_client	cleaning up solver	{"identifier": "a.crossbar.org", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.a.crossbar.org\" (usually OK if presenting also failed)"}
2022/10/27 20:36:41.669	ERROR	tls.obtain	could not get certificate from issuer	{"identifier": "a.crossbar.org", "issuer": "acme-v02.api.letsencrypt.org-directory", "error": "[a.crossbar.org] solving challenges: presenting for challenge: adding temporary record for zone \"crossbar.org.\": Error unquoting TXT/SPF record: invalid syntax (order=https://acme-v02.api.letsencrypt.org/acme/order/797591787/138525624177) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
2022/10/27 20:36:41.669	ERROR	tls.obtain	will retry	{"error": "[a.crossbar.org] Obtain: [a.crossbar.org] solving challenges: presenting for challenge: adding temporary record for zone \"crossbar.org.\": Error unquoting TXT/SPF record: invalid syntax (order=https://acme-v02.api.letsencrypt.org/acme/order/797591787/138525624177) (ca=https://acme-v02.api.letsencrypt.org/directory)", "attempt": 1, "retrying_in": 60, "elapsed": 4.141885193, "max_duration": 2592000}

5. What I already tried:

Google isn’t showing anything. Same with Caddy Community search. I am successfully generating certs for other domains, including ones that have subdomains, just not any for this one.

6. Links to relevant resources:

No idea

Looks like a bug in the route53 library that was fixed a few weeks ago. Make sure you’re using the latest version of it, or open a new issue there if the bug persists:

Thanks @matt for pointing me in the right direction.
I’m already using the latest so I’ll follow up there.
Cheers

1 Like

Hi, I trying to use caddy and route53 to automatically renew the certificate through caddy
However, whenever I set and run route53 tls, the following error appears even if I’m using route53 v1.3.0

I’ve been suffering from this problem for more than two days
Can you give me some advice on how to solve this problem?

(route) {
  tls {
    dns route53 {
      region ...
      access_key_id ...
      secret_access_key ...
    }
  }
}

my.routing.com {
  reverse_proxy staging.routing.com
  import route
}

Following is log

2022/11/23 08:11:39.862 e[34mINFOe[0m   tls.issuance.acme       waiting on internal rate limiter        {"identifiers": ["my.routing.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2022/11/23 08:11:39.862 e[34mINFOe[0m   tls.issuance.acme       done waiting on internal rate limiter   {"identifiers": ["my.routing.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2022/11/23 08:11:40.978 e[34mINFOe[0m   tls.issuance.acme.acme_client   trying to solve challenge       {"identifier": "my.routing.com", "challenge_type": "dns-01", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2022/11/23 08:11:43.056 e[31mERRORe[0m  tls.issuance.acme.acme_client   cleaning up solver      {"identifier": "my.routing.com", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for my.routing.com (probably OK if presenting failed)"}
2022/11/23 08:11:43.262 e[31mERRORe[0m  tls.obtain      could not get certificate from issuer   {"identifier": "my.routing.com", "issuer": "acme-v02.api.letsencrypt.org-directory", "error": "[my.routing.com] solving challenges: presenting for challenge: adding temporary record for zone routing.com.: Error unquoting TXT/SPF record: invalid syntax (order=https://acme-v02.api.letsencrypt.org/acme/order/732212697/146722220587) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
2022/11/23 08:11:43.264 e[33mWARNe[0m   tls.issuance.zerossl    missing email address for ZeroSSL; it is strongly recommended to set one for next time
2022/11/23 08:11:45.373 e[34mINFOe[0m   tls.issuance.zerossl    generated EAB credentials       {"key_id": "blabla"}

I’d suggest making a new post since your issue doesn’t seem related to the bug I discovered.
When you do make a new post, fill out the full template. Especially exactly which plugins you’re using, there are 2+ route53 plugins and they have subtle differences.

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.