<p>It seems that this is a bug in Bitcoin Core. I will take a look at it.</p>

<p>Edit:
I see the problem now. You have <code>#</code> in your password. The config file parse will interpret <code>#</code> as the beginning of a comment. So this means that it thinks the rest of your password is considered a comment by the config file. You cannot use <code>#</code> anywhere in the config file or everything after it will be interpreted as a comment.</p>

<p>In your example, the rpcpassword that Core is using is <code>!@</code>. To have <code>#</code> in your rpcpassword, I think you will actually need to use the <code>rpcauth</code> option which uses hashes instead of putting the password string in the config file.</p>

CC BY-SA 3.0
2017-06-21T21:35:33.043Z
Doh! This is so obvious in retrospect!
alexg
CC BY-SA 3.0
2017-06-21T18:05:59.937Z
2017-06-21T19:33:02.080Z
2017-06-21T19:33:02.080Z
Ava Chow
<p>When I set a simple password in my <code>.conf</code> file</p>

<pre><code>rpcuser=user
rpcpassword=password
</code></pre>

<p>I can contact my wallet using <code>curl</code> from the command line like so:</p>

<pre><code>$ curl --verbose --user 'user:password' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getbalance", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 18332 (#0)
* Server auth using Basic with user 'user'
&gt; POST / HTTP/1.1
&gt; Host: 127.0.0.1:18332
&gt; Authorization: Basic dXNlcjpwYXNzd29yZA==
&gt; User-Agent: curl/7.50.1
&gt; Accept: */*
&gt; content-type: text/plain;
&gt; Content-Length: 74
&gt; 
* upload completely sent off: 74 out of 74 bytes
&lt; HTTP/1.1 200 OK
&lt; Content-Type: application/json
&lt; Date: Τετ, 21 Ιούν 2017 08:59:30 GMT
&lt; Content-Length: 52
&lt; 
{"result":14.13139559,"error":null,"id":"curltest"}
* Connection #0 to host 127.0.0.1 left intact
</code></pre>

<p>But if I set a more complex password with special characters, such as</p>

<pre><code>rpcuser=user
rpcpassword=!@#$%^&amp;*()
</code></pre>

<p>then the call fails with 401 - Unauthorized</p>

<pre><code>$ curl --verbose --user 'user:!@#$%^&amp;*()' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getbalance", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 18332 (#0)
* Server auth using Basic with user 'user'
&gt; POST / HTTP/1.1
&gt; Host: 127.0.0.1:18332
&gt; Authorization: Basic dXNlcjohQCMkJV4mKigp
&gt; User-Agent: curl/7.50.1
&gt; Accept: */*
&gt; content-type: text/plain;
&gt; Content-Length: 74
&gt; 
* upload completely sent off: 74 out of 74 bytes
&lt; HTTP/1.1 401 Unauthorized
* Authentication problem. Ignoring this.
&lt; WWW-Authenticate: Basic realm="jsonrpc"
&lt; Date: Τετ, 21 Ιούν 2017 09:03:05 GMT
&lt; Content-Length: 0
&lt; Content-Type: text/html; charset=ISO-8859-1
&lt; 
* Connection #0 to host 127.0.0.1 left intact
</code></pre>

<p>It doesn't seem like the password was mangled at the shell level. It was passed verbatim.</p>

<pre><code>$ echo dXNlcjohQCMkJV4mKigp | base64 -d
user:!@#$%^&amp;*()
</code></pre>

<p>There must be a way to do this, because <code>bitcoin-cli</code> works with the complex password just fine.</p>

<pre><code>$ bitcoin-cli getbalance
14.13139559
</code></pre>

<p>Looking into <code>bitcoin-cli.cpp</code> it seems the client is using basic HTTP auth, which is consistent with what the wiki says.</p>

<pre><code>strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", "");
</code></pre>

<p>...and later on...</p>

<pre><code>evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
</code></pre>

<p>Can someone please figure this out for me?</p>

<p>I want to know because I'm trying to pass complex passwords into <a href="https://github.com/aceat64/EasyBitcoin-PHP" rel="nofollow noreferrer">EasyBitcoin-PHP</a> and failing.</p>

<p>Thanks.</p>

<json-rpc><bitcoin-cli>
How to pass password with special characters to RPC API via curl?
alexg
# How to pass password with special characters to RPC API via curl?

(Asked by: username_0 on 2017-06-21)

When I set a simple password in my `.conf` file

```
rpcuser=user
rpcpassword=password

```

I can contact my wallet using `curl` from the command line like so:

```
$ curl --verbose --user 'user:password' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getbalance", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 18332 (#0)
* Server auth using Basic with user 'user'
> POST / HTTP/1.1
> Host: 127.0.0.1:18332
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.50.1
> Accept: */*
> content-type: text/plain;
> Content-Length: 74
> 
* upload completely sent off: 74 out of 74 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Τετ, 21 Ιούν 2017 08:59:30 GMT
< Content-Length: 52
< 
{"result":14.13139559,"error":null,"id":"curltest"}
* Connection #0 to host 127.0.0.1 left intact

```

But if I set a more complex password with special characters, such as

```
rpcuser=user
rpcpassword=!@#$%^&*()

```

then the call fails with 401 - Unauthorized

```
$ curl --verbose --user 'user:!@#$%^&*()' --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getbalance", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 18332 (#0)
* Server auth using Basic with user 'user'
> POST / HTTP/1.1
> Host: 127.0.0.1:18332
> Authorization: Basic dXNlcjohQCMkJV4mKigp
> User-Agent: curl/7.50.1
> Accept: */*
> content-type: text/plain;
> Content-Length: 74
> 
* upload completely sent off: 74 out of 74 bytes
< HTTP/1.1 401 Unauthorized
* Authentication problem. Ignoring this.
< WWW-Authenticate: Basic realm="jsonrpc"
< Date: Τετ, 21 Ιούν 2017 09:03:05 GMT
< Content-Length: 0
< Content-Type: text/html; charset=ISO-8859-1
< 
* Connection #0 to host 127.0.0.1 left intact

```

It doesn't seem like the password was mangled at the shell level. It was passed verbatim.

```
$ echo dXNlcjohQCMkJV4mKigp | base64 -d
user:!@#$%^&*()

```

There must be a way to do this, because `bitcoin-cli` works with the complex password just fine.

```
$ bitcoin-cli getbalance
14.13139559

```

Looking into `bitcoin-cli.cpp` it seems the client is using basic HTTP auth, which is consistent with what the wiki says.

```
strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", "");

```

...and later on...

```
evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());

```

Can someone please figure this out for me?

I want to know because I'm trying to pass complex passwords into [EasyBitcoin-PHP](https://github.com/aceat64/EasyBitcoin-PHP) and failing.

Thanks.

**Tags:** json-rpc, bitcoin-cli


---

## 1 answers

### Answer by username_1 on 2017-06-21. Score: 2 | Accepted answer

It seems that this is a bug in Bitcoin Core. I will take a look at it.

Edit:
I see the problem now. You have `#` in your password. The config file parse will interpret `#` as the beginning of a comment. So this means that it thinks the rest of your password is considered a comment by the config file. You cannot use `#` anywhere in the config file or everything after it will be interpreted as a comment.

In your example, the rpcpassword that Core is using is `!@`. To have `#` in your rpcpassword, I think you will actually need to use the `rpcauth` option which uses hashes instead of putting the password string in the config file.

> **Comments:**
> **username_0**: Doh! This is so obvious in retrospect!  

---

