My problem was a variation on the one described by @kinzleb (or perhaps the same).
Somehow, the IAM Role attached to my Glue job got set to a customer-managed role† ARN, like this:
arn:aws:iam::000011110000:role/AWSGlueService
Whereas my other (working) jobs had a service role ARN, like this:
arn:aws:iam::000011110000:role/service-role/AWSGlueServiceRole
I wasn't able to discover the difference in the AWS Console because the UI doesn't make it possible to differentiate between a customer-managed and a service role (you can't see the ARN), but I compared a examples of working and non-working jobs via the AWS CLI like so:
$ aws glue --region my-aws-region get-job --job-name my_working_job | jq .Job.Role
"arn:aws:iam::000011110000:role/service-role/AWSGlueServiceRole"
$ aws glue --region my-aws-region get-job --job-name my_failing_job | jq .Job.Role
"arn:aws:iam::000011110000:role/role/AWSGlueServiceRole"
I confirmed via the IAM console that I don't even have a customer-managed role with that ARN. I only have the service-managed role. The error message is highly-misleading to the point of obfuscation.
I solved the problem by using $ aws glue --region my-aws-region update-job --job-name my-failing-job --job-update ...
from the command line to assign the service role to the job.
If this issue is introduced by a console bug, shame on AWS for having it still be there many years after @kinzleb's answer! And AWS, please update your stuff so I can differentiate between customer-managed and service roles within the Glue console website!
*: I anonymized the AWS account ID, hence the fake-looking 000011110000
.
†: "Customer-managed role" is fancy AWS-speak for "a role managed by me, the customer, who owns my AWS account and can create roles in it". Used in distinction to "service role" which is when the service creates the role in my account on my behalf and keeps it updated (these ones have /service-role/
in the ARN path) and also in distinction to service-linked roles which are another concept altogether and have /aws-service-role/
in the ARN path... Phew.