I am trying to create a new node with POST through REST in D8. I have enabled the relevant modules (hal, serialization, http basic authentication, Rest web services, rest ui) and added the required permissions to users (create content). I configured the services with restui and added basic_auth for authentication and allowed post on my endpoints. I send X-CSRF-Token together with Content-Type json (or jal+json as configured) and I get either a login popup (basic auth style with user/pass) in restlet client and a 401 Unauthorized with this response.

{ "message": "No authentication credentials provided." }

I even tried using cURL from command line to create my node, with the same result and a GuzzleHttp Exception.

PHP Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: POST http://www.xxxxxx.com/loyalty/node/?_format=json resulted in a 401 Unauthorized response: {"message":"No authentication credentials provided."} ' in /home/xxxxx/public_html/loyalty/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113

If I allow anonymous to create articles and disable basic_auth everything works fine.

Any clues?

3 Answers 3


Can you post an exact curl request? Does the user in your request have permission to create content?

if basic auth is enabled then you need to add the user name and password to the request. For example curl request:

curl --include \
  --request POST \
  --user admin:admin \
  --header 'Content-type: application/hal+json' \
  https://ddj9.ply.st/node?_format=hal_json \
  --data-binary '{"_links":{"type":{"href":"http://ddj9.ply.st/rest/type/node/article"}},"title":[{"value":"Example node title"}],"type":[{"target_id":"article"}]}'

Otherwise If the user must be authenticated via cookie then: 1. you have to send a post to login the user.

curl --header "Content-type: application/json" --request POST --data '{"name":"admin", "pass":"admin"}' http://drupal.d8/user/login?_format=json

The output will look like:

  1. Retrive a token from the returned value result
  2. Do what you need to do. :

    // get X-CSRF-Token.
    $url = 'your_url';
    $json = '{
    "name": "admin",
    "pass": "PASSWORD"
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
     'Content-Type: application/json')
    $result = curl_exec($ch);
    $user = json_decode($result, TRUE);
    $x_csrf_token = $user['csrf_token']
    if ($x_csrf_token) {
        // do what you need  
     curl_setopt_array($curl, array(
      CURLOPT_URL => "http://www.xxxxxx.com/loyalty/node/?_format=json",
      CURLOPT_TIMEOUT => 30,
      CURLOPT_POSTFIELDS => $input,
      CURLOPT_HTTPHEADER => array(
       // if you need basic auth then uncomment the nextline
       // "authorization: Basic b64Value",
        "cache-control: no-cache",
        "x-csrf-token: $x_csrf_token"
    $response = curl_exec($curl);

Had a similar issue when I switched from a laptop to another... on the old one there was no error, on the new one I got the same error. The authorization header was not coming in the server request. After some digging, I discovered that I didn't enable rewrite module on the new one. After enabling the module everything worked fine. So try sudo a2enmod rewrite


One possible cause can be that the IP address might be blocked by flood control. Check if your IP address is listed in the flood table. If it is, remove those entries or truncate the table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.