Agent.jar - 301 and redirect processing is not enabled

Hello, I am attempting to connect two Jenkins instances, both running 2.346.2. The controller instance is on Rocky Linux 8 and the agent is on Windows Server 2019. Both servers are running Bellsoft Liberica JDK 11.0.

I downloaded agent.jar onto our Windows agent and put it in the same c:\Program Files\Jenkins\ folder as the main install. When running the command from powershell I get the following error:

PS C:\Program Files\Jenkins> java -jar agent.jar -jnlpUrl https://<serverHostnameHere>/computer/vic%2Dwin%2Djenkins/jenkins-agent.jnlp -secret somelongseceretkeythatshouldntgoontheinternet -workDir "c:\JenkinsWorkDir"
Jul. 19, 2022 4:01:12 P.M. org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
INFO: Using c:\JenkinsWorkDir\remoting as a remoting work directory
Jul. 19, 2022 4:01:13 P.M. org.jenkinsci.remoting.engine.WorkDirManager setupLogging
INFO: Both error and output logs will be printed to c:\JenkinsWorkDir\remoting
Jul. 19, 2022 4:01:14 P.M. hudson.remoting.jnlp.Main createEngine
INFO: Setting up agent: vic-win-jenkins
Jul. 19, 2022 4:01:14 P.M. hudson.remoting.jnlp.Main$CuiListener <init>
INFO: Jenkins agent is running in headless mode.
Jul. 19, 2022 4:01:14 P.M. hudson.remoting.Engine startEngine
INFO: Using Remoting version: 4.13.2
Jul. 19, 2022 4:01:14 P.M. org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
INFO: Using c:\JenkinsWorkDir\remoting as a remoting work directory
Jul. 19, 2022 4:01:14 P.M. hudson.remoting.jnlp.Main$CuiListener error
SEVERE: Handshake error.
io.jenkins.remoting.shaded.javax.websocket.DeploymentException: Handshake error.
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:658)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:696)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:849)
        at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:493)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:337)
        at hudson.remoting.Engine.runWebSocket(Engine.java:668)
        at hudson.remoting.Engine.run(Engine.java:500)
Caused by: io.jenkins.remoting.shaded.org.glassfish.tyrus.client.RedirectException: Received HTTP response status code: 301 and redirect processing is not enabled.
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.TyrusClientEngine.handleRedirect(TyrusClientEngine.java:381)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.client.TyrusClientEngine.processResponse(TyrusClientEngine.java:261)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.ClientFilter.processRead(ClientFilter.java:167)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:111)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:113)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:113)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:294)
        at io.jenkins.remoting.shaded.org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:278)
        at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
        at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:282)
        at java.base/sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ReadTask.completed(WindowsAsynchronousSocketChannelImpl.java:581)
        at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:387)
        at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)

I’ve started searching through settings in Jenkins but didn’t find anything directly applicable. I tried turning on the “Agents” - TCP port for inbound agents setting but it didn’t change anything. Does anyone have any hints as to where the 301 redirect processing setting might be? I can’t tell if this is a client or server side issue either. Any input would be fantastic.

Thanks!
Russell

That’s not how agents in jenkins work. The are meant for spawing workers for the controller, but do not allow controll or communucation with aonther jenkins instance.

If you really want to communicate with another jenkins instance I think existis a plugin( well it is 9 years old, not supported and has security issues). I would go for just calling the jenkins api of the remote instance either via https or ssh.

Well that makes way more sense then what I was trying! I have removed Jenkins from the Windows server and downloaded the agent file to another directory. I realized the URL was using http instead of https so I corrected that in the jenkins (controller) configuration. I am now getting an error:

Caused by: io.jenkins.remoting.shaded.org.glassfish.tyrus.core.HandshakeException: Response code was not 101: 400.

I wonder if nginx (reverse proxy) is incorrectly configured. I have found an article on websocket pass through: Using NGINX as a WebSocket Proxy and will work through that.

Thanks for the help!

1 Like

I had to slightly modify the conf file to redirect 80 to 443 but that has fixed my issues.

upstream jenkins {
  keepalive 32; # keepalive connections
  server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
    listen 80;
    server_name jenkins.example.com;
    return 301 https://$host$request_uri;
    }
	
server {
	listen          443;       # Listen on port 80 for IPv4 requests  
	server_name     jenkins.example.com
	ssl_certificate           /etc/pki/tls/certs/fullchain.pem;
	ssl_certificate_key       /etc/pki/tls/private/privkey.pem;
	ssl on;
	ssl_session_cache  builtin:1000  shared:SSL:10m;
	ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;
	# this is the jenkins web root directory
	# (mentioned in the output of "systemctl cat jenkins")
	#root            /var/run/jenkins/war/;
	root            /var/cache/jenkins/war;

	access_log      /var/log/nginx/jenkins.access.log;
	error_log       /var/log/nginx/jenkins.error.log;

	# pass through headers from Jenkins that Nginx considers invalid
	ignore_invalid_headers off;

	location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
		# rewrite all static files into requests to the root
		# E.g /static/12345678/css/something.css will become /css/something.css
		rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
	}

	location /userContent {
		# have nginx handle all the static requests to userContent folder
		# note : This is the $JENKINS_HOME dir
		#root /var/lib/jenkins/;
		root /opt/data/jenkins;
		if (!-f $request_filename){
			# this file does not exist, might be a directory or a /**view** url
			rewrite (.*) /$1 last;
			break;
		}
		sendfile on;
	}

	location / {
		sendfile off;
		proxy_pass         http://jenkins;
		proxy_redirect     http://jenkins https://jenkins.example.com;
		proxy_http_version 1.1;

		# Required for Jenkins websocket agents
		proxy_set_header   Connection        $connection_upgrade;
		proxy_set_header   Upgrade           $http_upgrade;

		proxy_set_header   Host              $host;
		proxy_set_header   X-Real-IP         $remote_addr;
		proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
		proxy_set_header   X-Forwarded-Proto $scheme;
		proxy_max_temp_file_size 0;

		#this is the maximum upload size
		client_max_body_size       10m;
		client_body_buffer_size    128k;

		proxy_connect_timeout      90;
		proxy_send_timeout         90;
		proxy_read_timeout         90;
		proxy_buffering            off;
		proxy_request_buffering    off; # Required for HTTP CLI commands
		proxy_set_header Connection ""; # Clear for keepalive
	}
}

Thank you!