cpu: Thank you @sydneyli :1st_place_medal: :racing_car: 
diff --git a/acme/acme/client.py b/acme/acme/client.py
index d52c82a5c..9e2478afe 100644
--- a/acme/acme/client.py
+++ b/acme/acme/client.py
@@ -227,8 +227,7 @@ class ClientBase(object):  # pylint: disable=too-many-instance-attributes
         response = self._post(url,
                               messages.Revocation(
                                 certificate=cert,
-                                reason=rsn),
-                                content_type=None)
+                                reason=rsn))
         if response.status_code != http_client.OK:
             raise errors.ClientError(
                 'Successful revocation must return HTTP OK status')

`acme` module's `client._revoke` sends incorrect `ContentType` header.
[ACME draft-10, section 6.2](https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-6.2) explicitly requires POSTs be sent with a `Content-Type` of `application/jose+json`: 

> Because client requests in ACME carry JWS objects in the Flattened
> JSON Serialization, they must have the "Content-Type" header field
> set to "application/jose+json".  If a request does not meet this
> requirement, then the server MUST return a response with status code
> 415 (Unsupported Media Type).

The good news is that Certbot & the `acme` module already do this in 99.99% of cases :tada: :+1: :balloon: 

The bad news is that `client._revoke` overrides the default (correct) `ContentType` with `none`: https://github.com/certbot/certbot/blob/77fdb4d7d6194989dcc775f2e0ad81b6147c2359/acme/acme/client.py#L231

This will make revocation requests fail in a world where this restriction is enforced (See https://github.com/letsencrypt/boulder/pull/3532) 

There doesn't seem to be a reason to want to override `ContentType` in this case so I believe the fix is to change `_revoke` to use the default.

Thanks!
diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py
index a0c27e74f..00b9e19dd 100644
--- a/acme/acme/client_test.py
+++ b/acme/acme/client_test.py
@@ -635,8 +635,7 @@ class ClientTest(ClientTestBase):
     def test_revoke(self):
         self.client.revoke(self.certr.body, self.rsn)
         self.net.post.assert_called_once_with(
-            self.directory[messages.Revocation], mock.ANY, content_type=None,
-            acme_version=1)
+            self.directory[messages.Revocation], mock.ANY, acme_version=1)
 
     def test_revocation_payload(self):
         obj = messages.Revocation(certificate=self.certr.body, reason=self.rsn)
@@ -776,8 +775,7 @@ class ClientV2Test(ClientTestBase):
     def test_revoke(self):
         self.client.revoke(messages_test.CERT, self.rsn)
         self.net.post.assert_called_once_with(
-            self.directory["revokeCert"], mock.ANY, content_type=None,
-            acme_version=2)
+            self.directory["revokeCert"], mock.ANY, acme_version=2)
 
 
 class MockJSONDeSerializable(jose.JSONDeSerializable):

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pylint
apt-get update apt-get install -y gcc
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
acme==1.23.0
astroid==1.3.5
attrs==22.2.0
backcall==0.2.0
bleach==4.1.0
-e git+https://github.com/certbot/certbot.git@e0ae356aa35adf22d154113e06dd01409df93bba#egg=certbot
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
colorama==0.4.5
ConfigArgParse==1.7
configobj==5.0.8
coverage==6.2
cryptography==40.0.2
decorator==5.1.1
dill==0.3.4
distlib==0.3.9
docutils==0.18.1
execnet==1.9.0
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
ipdb==0.13.13
ipython==7.16.3
ipython-genutils==0.2.0
isort==5.10.1
jedi==0.17.2
jeepney==0.7.1
josepy==1.13.0
keyring==23.4.1
lazy-object-proxy==1.7.1
logilab-common==1.9.7
mccabe==0.7.0
mock==5.2.0
mypy-extensions==1.0.0
packaging==21.3
parsedatetime==2.6
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
pkginfo==1.10.0
platformdirs==2.4.0
pluggy==1.0.0
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
pycparser==2.21
Pygments==2.14.0
pylint==1.4.2
pyOpenSSL==23.2.0
pyparsing==3.1.4
pyRFC3339==2.0.1
pytest==7.0.1
pytest-cov==4.0.0
pytest-xdist==3.0.2
pytz==2025.2
readme-renderer==34.0
requests==2.27.1
requests-toolbelt==1.0.0
rfc3986==1.5.0
SecretStorage==3.3.3
six==1.17.0
toml==0.10.2
tomli==1.2.3
tox==3.28.0
tqdm==4.64.1
traitlets==4.3.3
twine==3.8.0
typed-ast==1.5.5
typing_extensions==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
wcwidth==0.2.13
webencodings==0.5.1
wrapt==1.16.0
zipp==3.6.0
zope.component==5.1.0
zope.event==4.6
zope.hookable==5.4
zope.interface==5.5.2

name: certbot
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - acme==1.23.0
      - astroid==1.3.5
      - attrs==22.2.0
      - backcall==0.2.0
      - bleach==4.1.0
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - colorama==0.4.5
      - configargparse==1.7
      - configobj==5.0.8
      - coverage==6.2
      - cryptography==40.0.2
      - decorator==5.1.1
      - dill==0.3.4
      - distlib==0.3.9
      - docutils==0.18.1
      - execnet==1.9.0
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - ipdb==0.13.13
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - isort==5.10.1
      - jedi==0.17.2
      - jeepney==0.7.1
      - josepy==1.13.0
      - keyring==23.4.1
      - lazy-object-proxy==1.7.1
      - logilab-common==1.9.7
      - mccabe==0.7.0
      - mock==5.2.0
      - mypy-extensions==1.0.0
      - packaging==21.3
      - parsedatetime==2.6
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pkginfo==1.10.0
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pycparser==2.21
      - pygments==2.14.0
      - pylint==1.4.2
      - pyopenssl==23.2.0
      - pyparsing==3.1.4
      - pyrfc3339==2.0.1
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytest-xdist==3.0.2
      - pytz==2025.2
      - readme-renderer==34.0
      - requests==2.27.1
      - requests-toolbelt==1.0.0
      - rfc3986==1.5.0
      - secretstorage==3.3.3
      - six==1.17.0
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - tqdm==4.64.1
      - traitlets==4.3.3
      - twine==3.8.0
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - wrapt==1.16.0
      - zipp==3.6.0
      - zope-component==5.1.0
      - zope-event==4.6
      - zope-hookable==5.4
      - zope-interface==5.5.2
prefix: /opt/conda/envs/certbot

acme/acme/client_test.py::ClientTest::test_revoke acme/acme/client_test.py::ClientV2Test::test_revoke
acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_finalize_order_v1_fetch_chain_error acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_finalize_order_v1_success acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_finalize_order_v1_timeout acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_finalize_order_v2 acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_forwarding acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_init_acme_version acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_init_downloads_directory acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_new_account_and_tos acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_new_order_v1 acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_new_order_v2 acme/acme/client_test.py::BackwardsCompatibleClientV2Test::test_revoke acme/acme/client_test.py::ClientTest::test_agree_to_tos acme/acme/client_test.py::ClientTest::test_answer_challenge acme/acme/client_test.py::ClientTest::test_answer_challenge_missing_next acme/acme/client_test.py::ClientTest::test_check_cert acme/acme/client_test.py::ClientTest::test_check_cert_missing_location acme/acme/client_test.py::ClientTest::test_deactivate_account acme/acme/client_test.py::ClientTest::test_fetch_chain_max acme/acme/client_test.py::ClientTest::test_fetch_chain_no_up_link acme/acme/client_test.py::ClientTest::test_fetch_chain_single acme/acme/client_test.py::ClientTest::test_fetch_chain_too_many acme/acme/client_test.py::ClientTest::test_init_downloads_directory acme/acme/client_test.py::ClientTest::test_poll acme/acme/client_test.py::ClientTest::test_poll_and_request_issuance acme/acme/client_test.py::ClientTest::test_query_registration acme/acme/client_test.py::ClientTest::test_refresh acme/acme/client_test.py::ClientTest::test_register acme/acme/client_test.py::ClientTest::test_request_challenges acme/acme/client_test.py::ClientTest::test_request_challenges_custom_uri acme/acme/client_test.py::ClientTest::test_request_challenges_deprecated_arg acme/acme/client_test.py::ClientTest::test_request_challenges_unexpected_update acme/acme/client_test.py::ClientTest::test_request_challenges_wildcard acme/acme/client_test.py::ClientTest::test_request_domain_challenges acme/acme/client_test.py::ClientTest::test_request_issuance acme/acme/client_test.py::ClientTest::test_request_issuance_missing_location acme/acme/client_test.py::ClientTest::test_request_issuance_missing_up acme/acme/client_test.py::ClientTest::test_retry_after_date acme/acme/client_test.py::ClientTest::test_retry_after_invalid acme/acme/client_test.py::ClientTest::test_retry_after_missing acme/acme/client_test.py::ClientTest::test_retry_after_overflow acme/acme/client_test.py::ClientTest::test_retry_after_seconds acme/acme/client_test.py::ClientTest::test_revocation_payload acme/acme/client_test.py::ClientTest::test_revoke_bad_status_raises_error acme/acme/client_test.py::ClientTest::test_update_registration acme/acme/client_test.py::ClientV2Test::test_finalize_order_error acme/acme/client_test.py::ClientV2Test::test_finalize_order_success acme/acme/client_test.py::ClientV2Test::test_finalize_order_timeout acme/acme/client_test.py::ClientV2Test::test_new_account acme/acme/client_test.py::ClientV2Test::test_new_order acme/acme/client_test.py::ClientV2Test::test_poll_and_finalize acme/acme/client_test.py::ClientV2Test::test_poll_authorizations_failure acme/acme/client_test.py::ClientV2Test::test_poll_authorizations_success acme/acme/client_test.py::ClientV2Test::test_poll_authorizations_timeout acme/acme/client_test.py::ClientNetworkTest::test_check_response_conflict acme/acme/client_test.py::ClientNetworkTest::test_check_response_jobj acme/acme/client_test.py::ClientNetworkTest::test_check_response_not_ok_jobj_error acme/acme/client_test.py::ClientNetworkTest::test_check_response_not_ok_jobj_no_error acme/acme/client_test.py::ClientNetworkTest::test_check_response_not_ok_no_jobj acme/acme/client_test.py::ClientNetworkTest::test_check_response_ok_no_jobj_ct_required acme/acme/client_test.py::ClientNetworkTest::test_check_response_ok_no_jobj_no_ct acme/acme/client_test.py::ClientNetworkTest::test_del acme/acme/client_test.py::ClientNetworkTest::test_del_error acme/acme/client_test.py::ClientNetworkTest::test_init acme/acme/client_test.py::ClientNetworkTest::test_requests_error_passthrough acme/acme/client_test.py::ClientNetworkTest::test_send_request acme/acme/client_test.py::ClientNetworkTest::test_send_request_get_der acme/acme/client_test.py::ClientNetworkTest::test_send_request_post acme/acme/client_test.py::ClientNetworkTest::test_send_request_timeout acme/acme/client_test.py::ClientNetworkTest::test_send_request_user_agent acme/acme/client_test.py::ClientNetworkTest::test_send_request_verify_ssl acme/acme/client_test.py::ClientNetworkTest::test_urllib_error acme/acme/client_test.py::ClientNetworkTest::test_wrap_in_jws acme/acme/client_test.py::ClientNetworkTest::test_wrap_in_jws_v2 acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_get acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_head acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_head_get_post_error_passthrough acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_failed_retry acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_no_content_type acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_not_retried acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_successful_retry acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_wrong_initial_nonce acme/acme/client_test.py::ClientNetworkWithMockedResponseTest::test_post_wrong_post_response_nonce
acme/acme/client.py
acme/acme/client.py