NS1 DNS Challenge Supplies Wrong TXT Record?

Hi everyone,

I’m trying to use the DNS challenge function with NS1 and wildcard certs. However, I’m getting an invalid TXT record. I’m using the docker container in this way:

docker run -v /data/certs2/letsencrypt/:/etc/letsencrypt -v /root/ns1.ini:/ns1.ini:ro -it --name certbot --entrypoint "/bin/sh" -d certbot/certbot 
docker exec -it certbot pip install certbot-dns-nsone
docker exec -it certbot certbot certonly --agree-tos --non-interactive --email letsencrypt@ADOMAIN.com --dns-nsone --dns-nsone-credentials /ns1.ini --dns-nsone-propagation-seconds 60 --server https://acme-v02.api.letsencrypt.org/directory --debug -v -d *.MYDOMAIN.com -d MYDOMAIN.com

Pretty straight forward, really. Here’s the output:

root@server:~# docker run -v /data/certs2/letsencrypt/:/etc/letsencrypt -v /root/ns1.ini:/ns1.ini:ro -it --name certbot --entrypoint "/bin/sh" -d certbot/certbot 
af318ebb86882a02197d71d52ccf283c6df286e23fb8c4465e9c18c5cceda573
root@server:~# docker exec -it certbot pip install certbot-dns-nsone
Collecting certbot-dns-nsone
  Downloading certbot_dns_nsone-0.22.0-py2.py3-none-any.whl
Requirement already satisfied: zope.interface in /usr/local/lib/python2.7/site-packages (from certbot-dns-nsone)
Requirement already satisfied: acme>=0.21.1 in ./src/acme (from certbot-dns-nsone)
Requirement already satisfied: setuptools in /usr/local/lib/python2.7/site-packages (from certbot-dns-nsone)
Requirement already satisfied: certbot>=0.21.1 in ./src (from certbot-dns-nsone)
Requirement already satisfied: mock in /usr/local/lib/python2.7/site-packages (from certbot-dns-nsone)
Collecting dns-lexicon (from certbot-dns-nsone)
  Downloading dns-lexicon-2.1.24.tar.gz (43kB)
	100% |████████████████████████████████| 51kB 1.1MB/s 
Requirement already satisfied: cryptography>=0.8 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: josepy>=1.0.0 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: PyOpenSSL>=0.13 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: pyrfc3339 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: pytz in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: requests[security]>=2.4.1 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python2.7/site-packages (from acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: ConfigArgParse>=0.9.3 in /usr/local/lib/python2.7/site-packages (from certbot>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: configobj in /usr/local/lib/python2.7/site-packages (from certbot>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: parsedatetime>=1.3 in /usr/local/lib/python2.7/site-packages (from certbot>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: zope.component in /usr/local/lib/python2.7/site-packages (from certbot>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: funcsigs>=1; python_version < "3.3" in /usr/local/lib/python2.7/site-packages (from mock->certbot-dns-nsone)
Requirement already satisfied: pbr>=0.11 in /usr/local/lib/python2.7/site-packages (from mock->certbot-dns-nsone)
Collecting tldextract (from dns-lexicon->certbot-dns-nsone)
  Downloading tldextract-2.2.0-py2.py3-none-any.whl (52kB)
	100% |████████████████████████████████| 61kB 3.0MB/s 
Requirement already satisfied: future in /usr/local/lib/python2.7/site-packages (from dns-lexicon->certbot-dns-nsone)
Requirement already satisfied: idna>=2.1 in /usr/local/lib/python2.7/site-packages (from cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: asn1crypto>=0.21.0 in /usr/local/lib/python2.7/site-packages (from cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: cffi>=1.7 in /usr/local/lib/python2.7/site-packages (from cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: enum34 in /usr/local/lib/python2.7/site-packages (from cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: ipaddress in /usr/local/lib/python2.7/site-packages (from cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: urllib3<1.23,>=1.21.1 in /usr/local/lib/python2.7/site-packages (from requests[security]>=2.4.1->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/site-packages (from requests[security]>=2.4.1->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python2.7/site-packages (from requests[security]>=2.4.1->acme>=0.21.1->certbot-dns-nsone)
Requirement already satisfied: zope.event in /usr/local/lib/python2.7/site-packages (from zope.component->certbot>=0.21.1->certbot-dns-nsone)
Collecting requests-file>=1.4 (from tldextract->dns-lexicon->certbot-dns-nsone)
  Downloading requests_file-1.4.3-py2.py3-none-any.whl
Requirement already satisfied: pycparser in /usr/local/lib/python2.7/site-packages (from cffi>=1.7->cryptography>=0.8->acme>=0.21.1->certbot-dns-nsone)
Building wheels for collected packages: dns-lexicon
  Running setup.py bdist_wheel for dns-lexicon ... done
  Stored in directory: /root/.cache/pip/wheels/d7/c6/e9/f2c415d54d1a5b292f89d6dc7aed84d9b6b9f14dbfe2903f6f
Successfully built dns-lexicon
Installing collected packages: requests-file, tldextract, dns-lexicon, certbot-dns-nsone
Successfully installed certbot-dns-nsone-0.22.0 dns-lexicon-2.1.24 requests-file-1.4.3 tldextract-2.2.0
root@server:~# docker exec -it certbot certbot certonly --agree-tos --non-interactive --email letsencrypt@ADOMAIN.com --dns-nsone --dns-nsone-credentials /ns1.ini --dns-nsone-propagation-seconds 60 --server https://acme-v02.api.letsencrypt.org/directory --debug -v -d *.MYDOMAIN.com -d MYDOMAIN.com
Root logging level set at 10
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requested authenticator dns-nsone and installer None
Single candidate plugin: * dns-nsone
Description: Obtain certificates using a DNS TXT record (if you are using NS1 for DNS).
Interfaces: IAuthenticator, IPlugin
Entry point: dns-nsone = certbot_dns_nsone.dns_nsone:Authenticator
Initialized: <certbot_dns_nsone.dns_nsone.Authenticator object at 0x7ffff190eb10>
Prep: True
Selected authenticator <certbot_dns_nsone.dns_nsone.Authenticator object at 0x7ffff190eb10> and installer None
Plugins selected: Authenticator dns-nsone, Installer None
Picked account: <Account(RegistrationResource(body=Registration(status=u'valid', terms_of_service_agreed=None, contact=(u'mailto:letsencrypt@ADOMAIN.com',), agreement=u'https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf', key=JWKRSA(key=<ComparableRSAKey(<cryptography.hazmat.backends.openssl.rsa._RSAPublicKey object at 0x7ffff1a30110>)>)), uri=u'https://acme-v02.api.letsencrypt.org/acme/acct/31197425', new_authzr_uri=None, terms_of_service=u'https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'), 90a52ce644a660a6ff70d5a90a1a4f99, Meta(creation_host=u'0c713f0f2ed2', creation_dt=datetime.datetime(2018, 3, 15, 12, 32, 5, tzinfo=<UTC>)))>
Sending GET request to https://acme-v02.api.letsencrypt.org/directory.
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
https://acme-v02.api.letsencrypt.org:443 "GET /directory HTTP/1.1" 200 562
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 562
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:55:56 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:55:56 GMT
Connection: keep-alive

{
  "iI9TShkaJPQ": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
  "keyChange": "https://acme-v02.api.letsencrypt.org/acme/key-change",
  "meta": {
	"termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
  },
  "newAccount": "https://acme-v02.api.letsencrypt.org/acme/new-acct",
  "newNonce": "https://acme-v02.api.letsencrypt.org/acme/new-nonce",
  "newOrder": "https://acme-v02.api.letsencrypt.org/acme/new-order",
  "revokeCert": "https://acme-v02.api.letsencrypt.org/acme/revoke-cert"
}
Obtaining a new certificate
Generating key (2048 bits): /etc/letsencrypt/keys/0005_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0005_csr-certbot.pem
Requesting fresh nonce
Sending HEAD request to https://acme-v02.api.letsencrypt.org/acme/new-order.
https://acme-v02.api.letsencrypt.org:443 "HEAD /acme/new-order HTTP/1.1" 405 0
Received response:
HTTP 405
Server: nginx
Content-Type: application/problem+json
Content-Length: 103
Allow: POST
Replay-Nonce: Z7wOBmXFuE[...]WraS7fSJEYU
Expires: Thu, 15 Mar 2018 12:55:56 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:55:56 GMT
Connection: keep-alive


Storing nonce: Z7wOBmXFuE[...]WraS7fSJEYU
JWS payload:
{
  "status": "pending", 
  "identifiers": [
	{
	  "type": "dns", 
	  "value": "*.MYDOMAIN.com"
	}, 
	{
	  "type": "dns", 
	  "value": "MYDOMAIN.com"
	}
  ], 
  "resource": "new-order"
}
Sending POST request to https://acme-v02.api.letsencrypt.org/acme/new-order:
{
  "protected": "eyJub25jZSI6ICJaN3dPQm1YRnVFN3dkVnNVQ1JIRW05OHBRTl94a0ZVR1dyY[...]YWxnIjogIlJTMjU2In0", 
  "payload": "ewogICJzdGF0dX[...]W9ucy5jb20iCiAgICB9CiAgXSwgCiAgInJlc291cmNlIjogIm5ldy1vcmRlciIKfQ", 
  "signature": "AAki_sMP-SxOvnN8oJk0tDeJtut74yFdMCIK4PSBzxcsQn4XVZ4ltdyHNa4uY2uCY[...]3GtaMVkC1YDFDNM43tVsGROfkvvYOsQbwvjiYMskpj0A"
}
https://acme-v02.api.letsencrypt.org:443 "POST /acme/new-order HTTP/1.1" 201 560
Received response:
HTTP 201
Server: nginx
Content-Type: application/json
Content-Length: 560
Boulder-Requester: 31197425
Location: https://acme-v02.api.letsencrypt.org/acme/order/31197425/25823
Replay-Nonce: ppHTtpLo[...]RQmmUkI
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:55:56 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:55:56 GMT
Connection: keep-alive

{
  "status": "pending",
  "expires": "2018-03-22T12:55:56.582126455Z",
  "identifiers": [
	{
	  "type": "dns",
	  "value": "*.MYDOMAIN.com"
	},
	{
	  "type": "dns",
	  "value": "MYDOMAIN.com"
	}
  ],
  "authorizations": [
	"https://acme-v02.api.letsencrypt.org/acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw",
	"https://acme-v02.api.letsencrypt.org/acme/authz/qdc6wBu[...]rBOtlCkI"
  ],
  "finalize": "https://acme-v02.api.letsencrypt.org/acme/finalize/31197425/25823"
}
Storing nonce: ppHTtpLo[...]RQmmUkI
Sending GET request to https://acme-v02.api.letsencrypt.org/acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw.
https://acme-v02.api.letsencrypt.org:443 "GET /acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw HTTP/1.1" 200 657
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 657
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:55:56 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:55:56 GMT
Connection: keep-alive

{
  "identifier": {
	"type": "dns",
	"value": "MYDOMAIN.com"
  },
  "status": "valid",
  "expires": "2018-04-14T12:32:15Z",
  "challenges": [
	{
	  "type": "dns-01",
	  "status": "valid",
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032",
	  "token": "Adpv[...]iuWjjhfE",
	  "keyAuthorization": "Adpv[...]iuWjjhfE.eu1uO_Zjt[...]ZrFQ",
	  "validationRecord": [
		{
		  "hostname": "MYDOMAIN.com"
		}
	  ]
	}
  ],
  "wildcard": true
}
Sending GET request to https://acme-v02.api.letsencrypt.org/acme/authz/qdc6wBu[...]rBOtlCkI.
https://acme-v02.api.letsencrypt.org:443 "GET /acme/authz/qdc6wBu[...]rBOtlCkI HTTP/1.1" 200 665
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 665
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:55:56 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:55:56 GMT
Connection: keep-alive

{
  "identifier": {
	"type": "dns",
	"value": "MYDOMAIN.com"
  },
  "status": "pending",
  "expires": "2018-03-22T12:55:56Z",
  "challenges": [
	{
	  "type": "http-01",
	  "status": "pending",
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999790",
	  "token": "Cv4Hwz-spoYOw[...]MIPusfkQF574"
	},
	{
	  "type": "dns-01",
	  "status": "pending",
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791",
	  "token": "vxRzvJvTH[...]NsLfgVUL3FY0"
	}
  ]
}
Performing the following challenges:
dns-01 challenge for MYDOMAIN.com
dns-01 challenge for MYDOMAIN.com
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "PUT /v1/zones/MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT HTTP/1.1" 200 None
create_record: True
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "PUT /v1/zones/MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT HTTP/1.1" 400 36
create_record: False
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
JWS payload:
{
  "keyAuthorization": "Adpv[...]iuWjjhfE.eu1uO_Zjt[...]ZrFQ", 
  "type": "dns-01", 
  "resource": "challenge"
}
Sending POST request to https://acme-v02.api.letsencrypt.org/acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032:
{
  "protected": "eyJub2[...]yI6ICJSUzI1NiJ9", 
  "payload": "ewogICJ[...]bGVuZ2UiCn0", 
  "signature": "qR4mUxCG[...]XOvGYUueg"
}
https://acme-v02.api.letsencrypt.org:443 "POST /acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032 HTTP/1.1" 200 421
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 421
Boulder-Requester: 31197425
Link: <https://acme-v02.api.letsencrypt.org/acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw>;rel="up"
Location: https://acme-v02.api.letsencrypt.org/acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032
Replay-Nonce: SqNW99g[...]RjgjjuA
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:56:58 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:56:58 GMT
Connection: keep-alive

{
  "type": "dns-01",
  "status": "valid",
  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032",
  "token": "Adpv[...]iuWjjhfE",
  "keyAuthorization": "Adpv[...]iuWjjhfE.eu1uO_Zjt[...]ZrFQ",
  "validationRecord": [
	{
	  "hostname": "MYDOMAIN.com"
	}
  ]
}
Storing nonce: SqNW99g[...]RjgjjuA
JWS payload:
{
  "keyAuthorization": "vxRzvJvTH[...]NsLfgVUL3FY0.eu1uO_Zjt[...]ZrFQ", 
  "type": "dns-01", 
  "resource": "challenge"
}
Sending POST request to https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791:
{
  "protected": "eyJub25jZS[...]ImFsZyI6ICJSUzI1NiJ9", 
  "payload": "ewogIC[...]CJjaGFsbGVuZ2UiCn0", 
  "signature": "JnlEq472[...]bk1PsUOP3Zg"
}
https://acme-v02.api.letsencrypt.org:443 "POST /acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791 HTTP/1.1" 200 335
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 335
Boulder-Requester: 31197425
Link: <https://acme-v02.api.letsencrypt.org/acme/authz/qdc6wBu[...]rBOtlCkI>;rel="up"
Location: https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791
Replay-Nonce: QBG478fG[...]P1VTYbmiJJs
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:56:58 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:56:58 GMT
Connection: keep-alive

{
  "type": "dns-01",
  "status": "pending",
  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791",
  "token": "vxRzvJvTH[...]NsLfgVUL3FY0",
  "keyAuthorization": "vxRzvJvTH[...]NsLfgVUL3FY0.eu1uO_Zjt[...]ZrFQ"
}
Storing nonce: QBG478fG[...]P1VTYbmiJJs
Sending GET request to https://acme-v02.api.letsencrypt.org/acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw.
https://acme-v02.api.letsencrypt.org:443 "GET /acme/authz/1eUQ6kLrpCGp[...]MD3iS-EDfEuw HTTP/1.1" 200 657
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 657
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:57:01 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:57:01 GMT
Connection: keep-alive

{
  "identifier": {
	"type": "dns",
	"value": "MYDOMAIN.com"
  },
  "status": "valid",
  "expires": "2018-04-14T12:32:15Z",
  "challenges": [
	{
	  "type": "dns-01",
	  "status": "valid",
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/1eUQ6kLrpCGp[...]MD3iS-EDfEuw/3826745032",
	  "token": "Adpv[...]iuWjjhfE",
	  "keyAuthorization": "Adpv[...]iuWjjhfE.eu1uO_Zjt[...]ZrFQ",
	  "validationRecord": [
		{
		  "hostname": "MYDOMAIN.com"
		}
	  ]
	}
  ],
  "wildcard": true
}
Sending GET request to https://acme-v02.api.letsencrypt.org/acme/authz/qdc6wBu[...]rBOtlCkI.
https://acme-v02.api.letsencrypt.org:443 "GET /acme/authz/qdc6wBu[...]rBOtlCkI HTTP/1.1" 200 1031
Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 1031
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 15 Mar 2018 12:57:01 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 15 Mar 2018 12:57:01 GMT
Connection: keep-alive

{
  "identifier": {
	"type": "dns",
	"value": "MYDOMAIN.com"
  },
  "status": "invalid",
  "expires": "2018-03-22T12:55:56Z",
  "challenges": [
	{
	  "type": "http-01",
	  "status": "pending",
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999790",
	  "token": "Cv4Hwz-spoYOw[...]MIPusfkQF574"
	},
	{
	  "type": "dns-01",
	  "status": "invalid",
	  "error": {
		"type": "urn:ietf:params:acme:error:unauthorized",
		"detail": "Incorrect TXT record \"-AQLL1g4[...]UEfNOniunrvPc\" found at _acme-challenge.MYDOMAIN.com",
		"status": 403
	  },
	  "url": "https://acme-v02.api.letsencrypt.org/acme/challenge/qdc6wBu[...]rBOtlCkI/3826999791",
	  "token": "vxRzvJvTH[...]NsLfgVUL3FY0",
	  "keyAuthorization": "vxRzvJvTH[...]NsLfgVUL3FY0.eu1uO_Zjt[...]ZrFQ"
	}
  ]
}
Reporting to user: The following errors were reported by the server:

Domain: MYDOMAIN.com
Type:   unauthorized
Detail: Incorrect TXT record "-AQLL1g4[...]UEfNOniunrvPc" found at _acme-challenge.MYDOMAIN.com

To fix these errors, please make sure that your domain name was entered correctly and the DNS A/AAAA record(s) for that domain contain(s) the right IP address.
Cleaning up challenges
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
list_records: [{'content': u'-AQLL1g4[...]UEfNOniunrvPc', 'id': 'MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT', 'type': u'TXT', 'name': u'_acme-challenge.MYDOMAIN.com', 'ttl': 3600}]
records: [{'content': u'-AQLL1g4[...]UEfNOniunrvPc', 'id': 'MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT', 'type': u'TXT', 'name': u'_acme-challenge.MYDOMAIN.com', 'ttl': 3600}]
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "DELETE /v1/zones/MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT HTTP/1.1" 200 3
delete_record: True
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
list_records: []
records: []
Exiting abnormally:
Traceback (most recent call last):
  File "/usr/local/bin/certbot", line 11, in <module>
	load_entry_point('certbot', 'console_scripts', 'certbot')()
  File "/opt/certbot/src/certbot/main.py", line 1266, in main
	return config.func(config, plugins)
  File "/opt/certbot/src/certbot/main.py", line 1157, in certonly
	lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
  File "/opt/certbot/src/certbot/main.py", line 118, in _get_and_save_cert
	lineage = le_client.obtain_and_enroll_certificate(domains, certname)
  File "/opt/certbot/src/certbot/client.py", line 350, in obtain_and_enroll_certificate
	cert, chain, key, _ = self.obtain_certificate(domains)
  File "/opt/certbot/src/certbot/client.py", line 294, in obtain_certificate
	orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
  File "/opt/certbot/src/certbot/client.py", line 330, in _get_order_and_authorizations
	authzr = self.auth_handler.handle_authorizations(orderr, best_effort)
  File "/opt/certbot/src/certbot/auth_handler.py", line 82, in handle_authorizations
	self._respond(resp, best_effort)
  File "/opt/certbot/src/certbot/auth_handler.py", line 159, in _respond
	self._cleanup_challenges(active_achalls)
  File "/opt/certbot/src/certbot/auth_handler.py", line 304, in _cleanup_challenges
	self.auth.cleanup(achalls)
  File "/opt/certbot/src/certbot/plugins/dns_common.py", line 76, in cleanup
	self._cleanup(domain, validation_domain_name, validation)
  File "/usr/local/lib/python2.7/site-packages/certbot_dns_nsone/dns_nsone.py", line 54, in _cleanup
	self._get_nsone_client().del_txt_record(domain, validation_name, validation)
  File "/opt/certbot/src/certbot/plugins/dns_common_lexicon.py", line 55, in del_txt_record
	self.provider.delete_record(type='TXT', name=record_name, content=record_content)
  File "/usr/local/lib/python2.7/site-packages/lexicon/providers/nsone.py", line 176, in delete_record
	raise Exception('Record identifier could not be found.')
Exception: Record identifier could not be found.
Please see the logfiles in /var/log/letsencrypt for more details.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: MYDOMAIN.com
   Type:   unauthorized
   Detail: Incorrect TXT record
   "-AQLL1g4[...]UEfNOniunrvPc" found at
   _acme-challenge.MYDOMAIN.com

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.
root@server:~# 

Any ideas what could be going on?

Hmmm… Perhaps this is the problem?

Performing the following challenges:
dns-01 challenge for MYDOMAIN.com
dns-01 challenge for MYDOMAIN.com
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "PUT /v1/zones/MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT HTTP/1.1" 200 None
create_record: True
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "GET /v1/zones/MYDOMAIN.com HTTP/1.1" 200 None
Starting new HTTPS connection (1): api.nsone.net
https://api.nsone.net:443 "PUT /v1/zones/MYDOMAIN.com/_acme-challenge.MYDOMAIN.com/TXT HTTP/1.1" 400 36
create_record: False

It looks like from this post https://blog.v-gar.de/2018/03/how-to-create-wildcard-certificates-with-lets-encrypt/ that there should be two TXT records created for the acme-challenge name with different values, but the nsone API may be attempting to overwrite the original? (notice the create_record: False). When I check my NS1 dashboard, there is only one value in the acme-challenge.

That sounds like it would be the problem. Some existing DNS-01 hooks weren't written to support setting more than one TXT value and will need to be updated to do so.

Yup, figured it out by testing the API with curl. Submitted an issue here: https://github.com/certbot/certbot/issues/5735

Update
I provided a methodology to fix in the issue. NS1 does have a multi-answer API call, it’s just not being used in the plugin.

1 Like

Great! Thanks for doing the leg work to get that into a Certbot issue @fmstrat, appreciated!

1 Like

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