While there are various forms of bulk copy this blog specifically deals with copying data from a file into SQL Server. It deals about the specific error “Operating system error code 5(Access is denied.)” which might crop up under certain circumstances when doing a bulk copy. For a while now I worked with a lot of DBAs and Developers bewildered with the problem and most of them complaining about the lack of good documentation about it and hours spent diagnosing in the wrong direction. If you are looking for details about bulk copy visit http://msdn.microsoft.com/en-us/library/ms130809(SQL.90).aspx
You run the following query
BULK INSERT ENVPOT_R
WITH ( FIELDTERMINATOR = ';', ROWTERMINATOR = '\n')
And end up getting the following error
Msg 4861, Level 16, State 1, Line 1
Cannot bulk load because the file
"\\advdev64\BulkTest\test_bulk_insert.txt" could not be opened.
Operating system error code 5(Access is denied.).
The usual troubleshooting that DBAs do is to chase the “Access Denied” error from a file/folder access perspective. Some of them are as follows.
a) Added “full” access to “everyone” (just temporary to test this) on the BulkTest folder and still getting the same error.
b) Added “full” access to the SQL server service account on the BulkTest folder and still get the same error.
c) The user is made a member of the bulkadmin fixed server role.
Many DBAs come with prior experience on SQL Server 2000 where the following was true.
Once a user was authenticated, access to external files was based on the security profile of the SQL Server process. When the SQL Server process had read access to a file, for a user that did not have access to the file but was a member of the bulkadmin fixed server role, the user could import the file by using BULK INSERT and access the contents of the file.
But that had a security issue and the way SQL Server 2005 and later versions handle access to external files is different.
The following are the salient points you need to keep in consideration and are also mentioned in detail here http://msdn.microsoft.com/en-us/library/ms175915(SQL.90).aspx
a) The data file must be shared between the two computers
b) To specify a shared data file, use its universal naming convention (UNC) name, which takes the general form of \\Servername\Sharename\Path\Filename.
c) The user account that is used by SQL Server must have been granted the permissions that are required for reading the file on the remote disk.
But there is another important consideration that needs to be taken care of when we have a setting as below and Windows authentication is being used.
Client application from client machine à SQL Server (SQL service account impersonating client account) \\File Server (impersonated client credentials)
a) We need to have CIFs SPN for the file server.
Whenever a computer is joined to a domain, it is assigned 2 SPN's by default: HOST/netbiosName, and HOST/FQDN.com. netbiosName being the machine name of the computer being joined to the domain, and FQDN.com being the fully qualified machine name. These two SPN's use the generic "HOST" service type which includes all the various services that *come*be default with Windows. Therefore, if we connect to http://machineName or http://machineName.company.com, we will already have SPN's set that will handle Kerberos when using those names. When trying to connect to \\machineName\SomeShareName we would be all set for Kerberos (UNC's need a "CIFS" SPN which is included under "HOST" also).
Complete list of the different service types included in HOST of can be found in this technet article.
b) Configuring Kerberos delegation on the SQL Server box.
The requirements are as follows.
i) A domain user running the query from management studio must not have the Account is sensitive and cannot be delegated selected option.
ii) SPNs must be registered for the SQL Server service if the service account is a domain account.
iii) The client must be connecting to the SQL using TCP. http://support.microsoft.com/default.aspx?scid=kb;EN-US;811889
The service’s SPN must be registered by a domain administrator if the service account is a domain user account. If the service account uses the computer’s account, then the process can register by itself or the local administrator can register it by using Setspn.
At a command prompt, type:
setspn –L Account domain\sqlServiceAccount
These two SPNs for SQL service account must come up for delegation to properly function:
•One for MSSQLSvc/Host:1433, where Host is the name of the host computer.
•One for MSSQLSvc/FQDN:1433 where FQDN is the fully qualified domain name of the computer running SQL Server .
The port number at the end may vary depending on the actual port the SQL Server is listening on. For the sake of brevity I have assumed the default port 1433.
If there are no MSSQLSvc SPNs listed or there is an SPN missing, then we need to add the appropriate SPN using the setspn –A command for delegation to work properly.
At a command prompt, type:
setspn -A MSSQLSvc/< Host >:<Port> <SQL_Service_Account>
setspn -A MSSQLSvc/<FQDN>:<Port> <SQL_Service_Account>
A sample is as below
setspn -A MSSQLSvc/MySQLServer:1433 domain\sqlServiceAccount
setspn -A MSSQLSvc/MySQLServer.MyDomain.com:1433 domain\sqlServiceAccount
iv)The SQL Server service account must be trusted for delegation.
Once the delegation is set properly the bulk copy should work fine and we shouldn’t get any errors.
I am not delving deep into Kerberos troubleshooting as the same is well documented in another blog by my colleague here. The same can be referred if we still continue getting Kerberos related errors.
Author : Angshuman(MSFT), SQL Developer Engineer, Microsoft
Reviewed by : SMAT(MSFT), SQL Escalation Services, Microsoft