Repository: aws/aws-cli

Issue:
`aws configure import --csv` Expected header 'User Name' not found yet exists in the CSV
### Describe the bug

Importing a configuration using the cli doesn't work. Producing an error that the expected header is not found yet is in the csv.

### Expected Behavior

Import the configuration and add the profile to the config.

### Current Behavior

PS C:\Users\DOUG> aws configure import --profile-prefix TheUnderground --csv file://"C:\Clients\TheUnderground\Credentials\Setup\Setup.csv" --debug
2023-03-04 12:02:30,561 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.11.0 Python/3.11.2 Windows/10 exe/AMD64
2023-03-04 12:02:30,561 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['configure', 'import', '--profile-prefix', 'TheUnderground', '--csv', 'file://C:\\Clients\\TheUnderground\\Credentials\\Setup\\Setup.csv', '--debug']
2023-03-04 12:02:30,607 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_s3 at 0x0000022E7CCB3920>
2023-03-04 12:02:30,607 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_ddb at 0x0000022E7CB00EA0>
2023-03-04 12:02:30,607 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.configure.configure.ConfigureCommand'>>
2023-03-04 12:02:30,608 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x0000022E7CA5D1C0>
2023-03-04 12:02:30,608 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x0000022E7CA80680>
2023-03-04 12:02:30,609 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function alias_opsworks_cm at 0x0000022E7CCC1E40>
2023-03-04 12:02:30,610 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_history_commands at 0x0000022E7CB37880>
2023-03-04 12:02:30,611 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.devcommands.CLIDevCommand'>>
2023-03-04 12:02:30,612 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_waiters at 0x0000022E7CCC1D00>
2023-03-04 12:02:30,612 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x0000022E7CD79DD0>>
2023-03-04 12:02:30,613 - MainThread - botocore.loaders - DEBUG - Loading JSON file: C:\Apps\Amazon\AWSCLIV2\awscli\data\cli.json
2023-03-04 12:02:30,617 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_types at 0x0000022E7CC09080>
2023-03-04 12:02:30,617 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function no_sign_request at 0x0000022E7CC093A0>
2023-03-04 12:02:30,617 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_verify_ssl at 0x0000022E7CC09300>
2023-03-04 12:02:30,618 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_read_timeout at 0x0000022E7CC094E0>
2023-03-04 12:02:30,618 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_connect_timeout at 0x0000022E7CC09440>
2023-03-04 12:02:30,619 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <built-in method update of dict object at 0x0000022E7CD771C0>
2023-03-04 12:02:30,619 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.11.0 Python/3.11.2 Windows/10 exe/AMD64 prompt/off
2023-03-04 12:02:30,620 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['configure', 'import', '--profile-prefix', 'TheUnderground', '--csv', 'file://C:\\Clients\\TheUnderground\\Credentials\\Setup\\Setup.csv', '--debug']
2023-03-04 12:02:30,620 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_timestamp_parser at 0x0000022E7CCC02C0>
2023-03-04 12:02:30,620 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function register_uri_param_handler at 0x0000022E7C7EE0C0>
2023-03-04 12:02:30,621 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_binary_formatter at 0x0000022E7CD37240>
2023-03-04 12:02:30,621 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function no_pager_handler at 0x0000022E7C7D27A0>
2023-03-04 12:02:30,621 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_assume_role_provider_cache at 0x0000022E7C8439C0>
2023-03-04 12:02:30,625 - MainThread - botocore.utils - DEBUG - IMDS ENDPOINT: http://169.254.169.254/
2023-03-04 12:02:30,627 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function attach_history_handler at 0x0000022E7CB34180>
2023-03-04 12:02:30,627 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_json_file_cache at 0x0000022E7CAF1120>
2023-03-04 12:02:30,628 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <function _add_wizard_command at 0x0000022E7CD35F80>
2023-03-04 12:02:30,628 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <function add_waiters at 0x0000022E7CCC1D00>
2023-03-04 12:02:30,629 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x0000022E7CD79DD0>>
2023-03-04 12:02:30,629 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure_import: calling handler <function add_waiters at 0x0000022E7CCC1D00>
2023-03-04 12:02:30,630 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure_import: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x0000022E7CD79DD0>>
2023-03-04 12:02:30,631 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.csv: calling handler <awscli.paramfile.URIArgumentHandler object at 0x0000022E7CDB5950>
2023-03-04 12:02:30,631 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x0000022E7C8B5650>
2023-03-04 12:02:30,631 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.skip-invalid: calling handler <awscli.paramfile.URIArgumentHandler object at 0x0000022E7CDB5950>
2023-03-04 12:02:30,632 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x0000022E7C8B5650>
2023-03-04 12:02:30,632 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.profile-prefix: calling handler <awscli.paramfile.URIArgumentHandler object at 0x0000022E7CDB5950>
2023-03-04 12:02:30,632 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x0000022E7C8B5650>
2023-03-04 12:02:30,633 - MainThread - awscli.clidriver - DEBUG - Exception caught in main()
Traceback (most recent call last):
  File "awscli\clidriver.py", line 460, in main
  File "awscli\customizations\commands.py", line 151, in __call__
  File "awscli\customizations\commands.py", line 205, in __call__
  File "awscli\customizations\configure\importer.py", line 95, in _run_main
  File "awscli\customizations\configure\importer.py", line 83, in _import_csv
  File "awscli\customizations\configure\importer.py", line 181, in parse_credentials
  File "awscli\customizations\configure\importer.py", line 164, in _parse_csv
  File "awscli\customizations\configure\importer.py", line 128, in _extract_expected_header_indices
awscli.customizations.configure.importer.CredentialParserError: Expected header "User Name" not found

Expected header "User Name" not found

### Reproduction Steps

Command:
aws configure import --profile-prefix TheUnderground --csv file://"C:\Clients\TheUnderground\Credentials\Setup\Setup.csv" --debug

C:\Clients\TheUnderground\Credentials\Setup\Setup.csv:
User Name,Password,Access key ID,Secret access key
Setup,,XX,XX


### Possible Solution

_No response_

### Additional Information/Context

_No response_

### CLI version used

aws-cli/2.11.0 Python/3.11.2 Windows/10 exe/AMD64 prompt/off

### Environment details (OS name and version, etc.)

Windows 10.0.19041.2673


Discussion:
Hi @gitaugakwa - thanks for reaching out. It sounds like you're missing `User Name` column in your CSV file. Could you edit the file and confirm if that fixes?

```
User Name,Access key ID,Secret access key
username,AKIAIOSFODNN7EXAMPLE,wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```
Best,
John

Edit: I'd like to clarify any confusion on my response here. Here are the steps I took to reproduce this:
- Download the credentials `.csv` file from the AWS console
- Open the file in `TextEdit` in Mac (NotePad in Windows?), add the header `User Name` and save it
- Run the CLI command `aws configure import --csv file://credentials.csv`
- Command works as expected and file was imported successfully

Based on the error the user was receiving `Expected header "User Name" not found`, my thought leading to my response was to verify and confirm that the header was added to the file correctly. 
John,

you are not seriously suggesting the above user doesn't know to check if they have a "User Name" header, are you?

That is not useful feelback.

I'm having the same problem and I see that many others are as well.  We all have the correct fields added with the correct case and spellings.

Something else is going on and the error message doesn't see me be helping.

This is all very frustrating.
Hi @robertdunaway - thanks for checking in and sorry to hear that you're seeing similar issue. 

I still wasn't able to reproduce it on my end after creating new IAM and credentials for that user. However, one of my colleagues was able to reproduce similar error and he was able to resolve it by creating a new `.csv` file with same headers `User Name,Access key ID,Secret access key`. We believe there must have been text encoding issue with the existing file. 

Please let us know if the issue persists and we'd be more than happy to further assist you.
I'm running `aws-cli/2.10.3` on macOS, and having the same issue, despite the CSV appearing entirely valid.

Checked the file's encoding:
```bash
$ file accessKeys.csv
accessKeys.csv: Unicode text, UTF-8 (with BOM) text, with CRLF line terminators
```

The header seems fine:
```bash
$ head -n 1 accessKeys.csv
User Name,Access key ID,Secret access key
```

but when I run the `import` command with `--debug` this is the output:

```bash
$ aws configure --debug import --csv "file://accessKeys.csv"
2023-03-09 19:44:16,106 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.10.3 Python/3.11.2 Darwin/22.1.0 source/x86_64
2023-03-09 19:44:16,106 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['configure', '--debug', 'import', '--csv', 'file://accessKeys.csv']
2023-03-09 19:44:16,130 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_s3 at 0x106ecdee0>
2023-03-09 19:44:16,130 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_ddb at 0x106a49260>
2023-03-09 19:44:16,130 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.configure.configure.ConfigureCommand'>>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x1069bdda0>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x1069bf420>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function alias_opsworks_cm at 0x106ee1a80>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_history_commands at 0x106d50cc0>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.devcommands.CLIDevCommand'>>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_waiters at 0x106ee0a40>
2023-03-09 19:44:16,131 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x106f88610>>
2023-03-09 19:44:16,131 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/data/cli.json
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_types at 0x106e194e0>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function no_sign_request at 0x106e19800>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_verify_ssl at 0x106e19760>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_read_timeout at 0x106e19940>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_connect_timeout at 0x106e198a0>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <built-in method update of dict object at 0x106f85940>
2023-03-09 19:44:16,133 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.10.3 Python/3.11.2 Darwin/22.1.0 source/x86_64 prompt/off
2023-03-09 19:44:16,133 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['configure', '--debug', 'import', '--csv', 'file://accessKeys.csv']
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_timestamp_parser at 0x106eceac0>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function register_uri_param_handler at 0x1067022a0>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_binary_formatter at 0x106f3f740>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function no_pager_handler at 0x1066d6980>
2023-03-09 19:44:16,133 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_assume_role_provider_cache at 0x1067642c0>
2023-03-09 19:44:16,140 - MainThread - botocore.utils - DEBUG - IMDS ENDPOINT: http://169.254.169.254/
2023-03-09 19:44:16,147 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function attach_history_handler at 0x106d504a0>
2023-03-09 19:44:16,147 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_json_file_cache at 0x106a3d260>
2023-03-09 19:44:16,147 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <function _add_wizard_command at 0x106f3e660>
2023-03-09 19:44:16,147 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <function add_waiters at 0x106ee0a40>
2023-03-09 19:44:16,147 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x106f88610>>
2023-03-09 19:44:16,148 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure_import: calling handler <function add_waiters at 0x106ee0a40>
2023-03-09 19:44:16,148 - MainThread - botocore.hooks - DEBUG - Event building-command-table.configure_import: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x106f88610>>
2023-03-09 19:44:16,148 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.csv: calling handler <awscli.paramfile.URIArgumentHandler object at 0x10672dcd0>
2023-03-09 19:44:16,149 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x1064ae5d0>
2023-03-09 19:44:16,149 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.skip-invalid: calling handler <awscli.paramfile.URIArgumentHandler object at 0x10672dcd0>
2023-03-09 19:44:16,149 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x1064ae5d0>
2023-03-09 19:44:16,149 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.import.profile-prefix: calling handler <awscli.paramfile.URIArgumentHandler object at 0x10672dcd0>
2023-03-09 19:44:16,149 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.import: calling handler <awscli.argprocess.ParamShorthandParser object at 0x1064ae5d0>
2023-03-09 19:44:16,149 - MainThread - awscli.clidriver - DEBUG - Exception caught in main()
Traceback (most recent call last):
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/clidriver.py", line 460, in main
    return command_table[parsed_args.command](remaining, parsed_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/commands.py", line 151, in __call__
    return self._subcommand_table[subcommand_name](
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/commands.py", line 205, in __call__
    rc = self._run_main(parsed_args, parsed_globals)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/configure/importer.py", line 95, in _run_main
    self._import_csv(parsed_args.csv)
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/configure/importer.py", line 83, in _import_csv
    credentials = self._csv_parser.parse_credentials(contents)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/configure/importer.py", line 181, in parse_credentials
    parsed_rows = self._parse_csv(contents)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/configure/importer.py", line 164, in _parse_csv
    header_indices = self._extract_expected_header_indices(parsed_headers)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/awscli/2.10.3/libexec/lib/python3.11/site-packages/awscli/customizations/configure/importer.py", line 128, in _extract_expected_header_indices
    raise CredentialParserError(self._HEADER_NOT_FOUND % header)
awscli.customizations.configure.importer.CredentialParserError: Expected header "User Name" not found

Expected header "User Name" not found
```
Edit - I was able to reproduce the issue after downloading the .csv file from IAM and adding a "User name" header/value to the file in Excel. However, once I opened and saved the file in a plain text editor then it worked as expected. Still not quite sure on the specific cause, possibly some hidden character encoding - but I think the credential parser should be able to handle this case.
Not sure how helpful this extra info is, but I changed the encoding from 'Unicode (UTF-8, with BOM)' to 'Unicode (UTF-8)' and that worked too.
> Hi @gitaugakwa - thanks for reaching out. It sounds like you're missing `User Name` column in your CSV file. Could you edit the file and confirm if that fixes?
> 
> ```
> User Name,Access key ID,Secret access key
> username,AKIAIOSFODNN7EXAMPLE,wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
> ```
> 
> Best, John

Haha, imagine coming all this way and being flummoxed coming across the CSV format for the first time. I'm guessing an encoding issue
I am experiencing the same issue, working on Windows 10.  
Doing `file -i accessKeys.csv` tells me that the charset is `utf-8`.
Opening in VSCode lists it as `utf8bom`, re-saving as plain `utf8` solves the issue.
> I am experiencing the same issue, working on Windows 10. Doing `file -i accessKeys.csv` tells me that the charset is `utf-8`. Opening in VSCode lists it as `utf8bom`, re-saving as plain `utf8` solves the issue.

This does in fact fix the issue. But does not resolve the problem. The csv was downloaded from the AWS IAM page and thus would expect the file to be compatible with the AWS CLI.

Either the CLI supports `utf8bom` or the Console downloads the file as `utf8`.


same, hours of just trying to get access. what a freaking joke
> > I am experiencing the same issue, working on Windows 10. Doing `file -i accessKeys.csv` tells me that the charset is `utf-8`. Opening in VSCode lists it as `utf8bom`, re-saving as plain `utf8` solves the issue.
> 
> This does in fact fix the issue. But does not resolve the problem. The csv was downloaded from the AWS IAM page and thus would expect the file to be compatible with the AWS CLI.
> 
> Either the CLI supports `utf8bom` or the Console downloads the file as `utf8`.
> 
> 

Yes, you are correct. I should choose my words more carefully. Resaving as a different encoding does not fix the problem, however it is a temporary workaround.
Thank you all for reporting. We totally understand your frustration and apologize for the inconvenience. I wanted to share that the team's aware of this behavior and will be looking into it. 

Meanwhile, please refer to one of these workarounds mentioned:
- change the encoding of the CSV file from `utf8bom` to `utf8` (**or**)
- re-save the file in a plain text editor with `User Name` header added

We'll keep it posted.
Hello I tried saving the .csv using vscode and UTF8 encoding and it doesn't help. I tried many solutions including the one you suggested aBurmeseDev but it doesn't work. Please help it's a bit urgent
I had to abandon the cvs file approach completely.  Even if I did get it working, at this point I can't trust it in production.  Nothing should be this buggy.

I am running my environment settings as part of the batch.  I don't like it but the CLI simply doesn't read the file correctly that aws gives us.  I can't trust it.    Then support gaslights us.  Nope... not trusting that.
> I had to abandon the cvs file approach completely. Even if I did get it working, at this point I can't trust it in production. Nothing should be this buggy.
> 
> I am running my environment settings as part of the batch. I don't like it but the CLI simply doesn't read the file correctly that aws gives us. I can't trust it. Then support gaslights us. Nope... not trusting that.

??? They acknowledged the issue. Literally the opposite of gaslighting. There's really no need to be rude.
The initial response is what I was referring to.  This problem was ignored until they were called out directly for dismissing it.  I wasn't trying to be rude.

Resolving patch:
diff --git a/awscli/customizations/configure/importer.py b/awscli/customizations/configure/importer.py
--- a/awscli/customizations/configure/importer.py
+++ b/awscli/customizations/configure/importer.py
@@ -12,8 +12,8 @@
 # language governing permissions and limitations under the License.
 import os
 import sys
+import codecs
 
-from awscli.compat import compat_open
 from awscli.customizations.utils import uni_print
 from awscli.customizations.commands import BasicCommand
 from awscli.customizations.configure.writer import ConfigFileWriter
@@ -115,6 +115,9 @@ def __init__(self, strict=True):
         self.strict = strict
 
     def _format_header(self, header):
+        # Remove leading UTF BOM character if present
+        if header.startswith(codecs.BOM_UTF8.decode()):
+            header = header[1:]
         return header.lower().strip()
 
     def _parse_csv_headers(self, header):


Test patch:
diff --git a/tests/unit/customizations/configure/test_importer.py b/tests/unit/customizations/configure/test_importer.py
--- a/tests/unit/customizations/configure/test_importer.py
+++ b/tests/unit/customizations/configure/test_importer.py
@@ -109,6 +109,13 @@ def test_csv_parser_simple(self):
         )
         self.assert_parse_matches_expected(contents)
 
+    def test_csv_parser_with_bom(self):
+        contents = (
+            u'\ufeffUser name,Access key ID,Secret access key\n'
+            'PROFILENAME,AKID,SAK\n'
+        )
+        self.assert_parse_matches_expected(contents)
+
     def test_csv_parser_multiple_entries(self):
         contents = (
             'User name,Access key ID,Secret access key\n'
@@ -121,6 +128,18 @@ def test_csv_parser_multiple_entries(self):
         ]
         self.assert_parse_matches_expected(contents)
 
+    def test_csv_parser_multiple_entries_bom(self):
+        contents = (
+            u'\ufeffUser name,Access key ID,Secret access key\n'
+            'PROFILENAME1,AKID1,SAK1\n'
+            'PROFILENAME2,AKID2,SAK2\n'
+        )
+        self.expected_credentials = [
+            ('PROFILENAME1', 'AKID1', 'SAK1'),
+            ('PROFILENAME2', 'AKID2', 'SAK2'),
+        ]
+        self.assert_parse_matches_expected(contents)
+
     def test_csv_parser_multiple_entries_with_bad_entries(self):
         self.parser.strict = False
         contents = (