Conflict if adding IPv6 ssl listen directive to nginx frappe-bench config

I’m seeing very strange behavior with my site: sometimes the site loads ERPNext which is sub2.domain.tld, but sometimes sub2.domain.tld loads the content from domain.tld instead. I might have found a hint as to the cause when trying to add an IPv6 listen directive to the nginx config for frappe-bench.

Here are my config files:

/etc/nginx/nginx.conf:

http {
	…
	include /etc/nginx/conf.d/*.conf; 
	…
}

/etc/nginx/conf.d/main.conf:

server {
	server_name domain.tld;
	…
	listen [::]:443 ssl http2 ipv6only=on;
	listen 443 ssl http2;
	…
}

server {
    if ($host = domain.tld) {
        return 301 https://$host$request_uri;
    }

	listen 80;
	listen [::]:80;
	server_name domain.tld;
		return 404;
}

/etc/nginx/conf.d/sub1.conf:

server {
	server_name sub1.domain.tld;
	…
	listen [::]:443 ssl http2 ipv6only=on;
	listen 443 ssl http2;
	…
}

server {
    if ($host = sub1.domain.tld) {
        return 301 https://$host$request_uri;
    }

	listen 80;
	listen [::]:80;
	server_name sub1.domain.tld;
		return 404;
}

/etc/nginx/conf.d/frappe-bench.conf:

server {
	server_name sub2.domain.tld;
	…
	listen [::]:443 ssl http2 ipv6only=on;
	listen 443 ssl http2;
	…
}

server {
    if ($host = sub2.domain.tld) {
        return 301 https://$host$request_uri;
    }

	listen 80;
	listen [::]:80;
	server_name sub2.domain.tld;
		return 404;
}

This results in an error:

$ nginx -t
duplicate listen options for [::]:443 in /etc/nginx/conf.d/main.conf

Only adding listen [::]:443 ssl http2 ipv6only=on; to the frappe-bench config causes the problem.

There is no conflict between sub1.domain.tld and domain.tld, only between sub2.domain.tld and domain.tld. There is no conflict between the IPv4 listen directives, or between the HTTP listen directives on port 80, only between IPv6 and HTTPS on port 443. Removing the ssl listen directive on frappe-bench.conf passes the test, even when sub1.conf keeps the same directives.