Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

security/acme-client: missing accounts directory causes DNS-01 validation failure

Open Beginner friendly
#5,763 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
php, shell
Domain
devops, security

Research direction

Start at the os-acme-client plugin entry point that launches acme.sh with --accountconf, then trace how the account configuration path is built. Verify the parent directory is created with the expected permissions before execution, and reproduce the DNS-01 flow to confirm account.conf can be written and validation reaches the DNS provider.

Written by the indexing model from the issue text.

Description

incomplete

Important notices
I have read the contributing guidelines.
I searched open and closed issues and did not find this specific issue.
Describe the bug
os-acme-client invokes acme.sh with an explicit account configuration path beneath:

/var/etc/acme-client/accounts/_prod/account.conf

However, on my system the accounts directory was not created.

This causes DNS-01 validation to fail before the DNS provider API is called.

Environment:

OPNsense 26.7.4_1 (amd64) os-acme-client 4.17 acme.sh 3.1.4 FreeBSD 15.1-RELEASE-p3 ACME CA: Let's Encrypt Challenge: DNS-01 DNS provider: DreamHost

Symptoms
Certificate configuration:

CN: ryanhome.us

SAN: *.ryanhome.us

The ACME operation failed with:

Error adding TXT record to domain: _acme-challenge.ryanhome.us domain validation failed (dns01)

Debug 3 showed:

ACCOUNT_CONF_PATH='/var/etc/acme-client/accounts/_prod/account.conf'

But the runtime directory contained only:

cert-home certs challenges configs home keys

There was no:

/var/etc/acme-client/accounts

Investigation
The installed DreamHost DNS provider calls validate() before submit().

validate() ends by calling:

_saveaccountconf_mutable DH_API_KEY "$DH_API_KEY"

_saveaccountconf_mutable ultimately writes to ACCOUNT_CONF_PATH.

In acme.sh 3.1.4, _setopt() does:

if [ ! -f "$__conf" ]; then touch "$__conf" chmod 600 "$__conf" fi

but it does not create the parent directory.

As a result, account.conf cannot be created when the parent directory does not exist. The DreamHost provider exits before submit() is reached.

Debug logging showed "Using dreamhost" and then the TXT-add failure, but no URL debug output from the provider's submit() function.

Verification that DreamHost is not the cause
From the same OPNsense shell, using the same DreamHost API key:

dns-list_records succeeds.

A manual dns-add_record also succeeds for:

_acme-challenge.ryanhome.us TXT

DreamHost returns:

{"result":"success","data":"record_added"}

The record is then visible using DreamHost's dns-list_records API.

I also tested a direct query-string request equivalent to that constructed by dns_dreamhost.sh, which also returns:

{"result":"success","data":"record_added"}

Workaround / reproduction proof
Before the workaround:

ls -ld /var/etc/acme-client/accounts

returned:

No such file or directory

I manually created:

mkdir -p /var/etc/acme-client/accounts/_prod

chmod 750 /var/etc/acme-client/accounts chmod 750 /var/etc/acme-client/accounts/_prod

I did NOT manually create account.conf and made no other ACME configuration changes.

I then issued the exact same certificate again.

The ACME log immediately progressed to:

response='success record_added' The TXT record has been successfully added. Sleeping for 120 seconds to wait for the TXT records to take effect

The certificate was subsequently issued successfully.

OPNsense now reports:

Last ACME Status: OK

and acme.sh automatically created:

/var/etc/acme-client/accounts/_prod/account.conf

with permissions 0600.

Expected behavior
os-acme-client should ensure the parent directory for the account configuration exists before invoking acme.sh with --accountconf.

For example:

/var/etc/acme-client/accounts/_prod/

should already exist before acme.sh is executed.

Additional information
The workaround is currently present under /var/etc and therefore may not survive reboot or runtime-directory recreation.

No modification to acme.sh or dns_dreamhost.sh was required.

Proposed Fix is conceptually like:

$accountConfDir = dirname($accountConf);
 
if (!is_dir($accountConfDir)) {
mkdir($accountConfDir, 0750, true);
}

immediately before the plugin launches acme.sh with:
--accountconf $accountConf

Before & After Workaround:

Before workaround:
 

ls -ld /var/etc/acme-client/accounts

ls: /var/etc/acme-client/accounts: No such file or directory

Workaround:
 
mkdir -p /var/etc/acme-client/accounts/_prod
chmod 750 /var/etc/acme-client/accounts
chmod 750 /var/etc/acme-client/accounts/_prod

No other ACME settings were changed.
 
The next issuance succeeded:
 
response='success record_added'
The TXT record has been successfully added.
Sleeping for 120 seconds to wait for the TXT records to take effect

Issue/Renewal Date: 10/3/2026 3:57:06 PM
Last ACME Status: OK

Environment
OPNsense 26.7.4_1 (amd64)
os-acme-client 4.17
acme.sh 3.1.4
FreeBSD 15.1-RELEASE-p3
ACME CA: Let's Encrypt
Challenge: DNS-01
DNS provider: DreamHost

Last known working os-acme-client version: Unknown.
This is a new pfSense-to-OPNsense migration, so I do not have an
earlier OPNsense plugin version known to work.

GUI pages involved:
Services > ACME Client > Certificates
Services > ACME Client > Challenge Types

Dominant language
PHP
Stars
1.2k
Forks
869
Avg merge
2d 4h
Merged PRs (30d)
13

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from opnsense/plugins

All issues in opnsense/plugins

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.