Why not just use the exit code from the command source ?
You don't have to use bash -n for this because ...
If let's say your .env file contains these 2 invalid lines:
dsadsd
sdss
If you run your current accepted code using the example above:
if errs=$(bash -n .env 2>&1); 
the above condition will fail to stop the file from sourcing.
So, you can use source command return code to handle all of this:
#!/bin/bash
# This doesn't actually source it. It just test if source is working
errs=$(source ".env" 2>&1 >/dev/null)
# get the return code
retval=$?
#echo "${retval}"
if [ ${retval} = 0 ]; then
  # Do another check for any syntax error
  if [ -n "${errs}" ]; then
    echo "The source file returns 0 but you got syntax errors: "
    echo "Error details:"
    printf "%s\n" "${errs}"
    exit 1
  else
    # Success here. we know that this command works without error so we source it
    echo "The source file returns 0 and no syntax errors: "
    source ".env"
  fi
else
  echo "The source command returns an error code ${retval}: "
  echo "Error details:"
  printf "%s\n" "${errs}"
  exit 1
fi
The best thing with this approach is, it will check both bash syntax and source syntax as well:
Now you can test this data in your env file:
-
~
@
~<
>